Categories: TSQL Tuesday

T-SQL Tuesday #15 DBA Automaton

Comments: 1 Comment
Published on: February 8, 2011

I have been incognito for the last couple of weeks and nearly missed TSQL Tuesday this month.  If it weren’t for somebody pinging me requesting the link to the list of upcoming hosts, I would have missed it entirely.  The topic merges well with the work I have been doing for the past few weeks.  In fact, there are so many things that DBA’s do on a regular basis to automate things – there should be plenty of items to cherry pick for a topic.  Unfortunately, that doesn’t make this topic any easier for me.  My decision process for this is partially based on thinking through what might be unique without having read what others may have written.  (While thinking about reading blogs, it would be nice if there was an automated method to ingest all of the blogs into my head without having to iterate through them one at a time – manually.)

This month the party is hosted by Pat Wright (blogtwitter).  Pat has asked us to describe some of the things we automate – or some of our automation that we have implemented.  Often, we hear about DBA’s automating everything under the sun.  Why?  It simplifies the job and creates time to work on other projects.  With all of the automation, I wonder if DBA’s are related to Hephaestus in any fashion.  If we had our way, it seems that our databases would be…Automatons.

A Lesser Automation

Now that I have rambled for a good bit, I guess it is time to get to the meat of the topic.  First, we need to understand automation.  So, what is automation?

  1. The automatic operation or control of equipment, a process, or a system.
  2. The techniques and equipment used to achieve automatic operation or control.

A closely related word to automation is:

  1. Computerization – the control of processes by computer

In other words, for a DBA, automation is the implementation of a process or control for the computer to operate without the DBA doing the work.  This is typically something that is repetitive or menial or tedious or frequently done.  But that is not always the case.  This can also be something that is fun and/or only done once or twice a year.

I have one of those cases where I may use the automation even less often than once a year, or maybe it could come about more frequently.  It all depends on the needs of designing and testing new databases.

This process is to help in properly sizing the database before the database is finally released to production.  With good project requirements, you may have a good idea of what the fields and sizes of those fields should be.  In some cases, you will be getting data from an external source in some fashion or another.  This data does not always come with storage requirements or data size parameters.  You can make guesses at it by looking at the data – but sometimes, something more is required.

It is when more is required that this script comes in a bit handy for me.  The script is ugly, but it does the deed.  The base idea is to retrieve the data length for a sample of data from each of the tables (after import into a staging database).  This is done so I can run statistical analysis on the data later.  And cringe now because I use a nested cursor to get at what I want.

So Here is the script that will load a sample of data from every table in every database for every column and give you the length of the pertinent columns (I have excluded obvious columns such as numeric types and certain LOB types).

IF exists (SELECT name FROM sys.objects WHERE name = 'DataLenStats_Alt')
BEGIN
	DROP TABLE DataLenStats_Alt
END
 
CREATE TABLE DataLenStats_Alt (DatabaseName sysname,TableName SYSNAME, ColumnName SYSNAME, ColLens INT)
 
DECLARE dbfetch CURSOR STATIC FOR
SELECT name
	FROM sys.databases
	WHERE database_id > 4
		And Name <> 'Admin'
	ORDER BY Name
 
OPEN dbfetch;
DECLARE @sql1 VARCHAR(MAX), @dbname VARCHAR(128)
 
FETCH NEXT FROM dbfetch
INTO @dbname;
 
WHILE @@FETCH_STATUS = 0
BEGIN
 
	SET @sql1 = '
	Use ' + @dbname +';
	DECLARE datalens_cursor CURSOR Static FOR
	SELECT Distinct IST.TABLE_NAME,IST.Column_Name
	FROM Information_schema.Columns IST
		Inner Join sys.dm_db_partition_stats AS st
			On object_id(IST.TABLE_NAME) = st.object_id
	WHERE ObjectProperty(object_id(Table_Name),''Ismsshipped'') = 0
		And Table_Name not like ''sysdi%''
		And DATA_TYPE not in (''XML'',''uniqueidentifier'',''image'')
		And isnull(numeric_precision,0)=0
	Group By Table_Name,Column_name
	Having Sum(st.row_count) > 0
	ORDER BY Table_name;
 
	OPEN datalens_cursor;
	declare @sql varchar(max), @table sysname, @column sysname
 
	FETCH NEXT FROM datalens_cursor
		INTO @table,@column;
 
	WHILE @@FETCH_STATUS = 0
	BEGIN
	Set @sql=''''
 
		select @sql=@sql+''select top 2 Percent db_name(),''''''+@table+'''''',''''''+@column+'''''', len(isnull(convert(varchar(max),''+@column+''),''+''0''+'')) from [''+@table+''] ''
							From information_schema.columns
								Where table_name=''''+@table+''''
									And column_name = ''''+@column+''''
 
		Begin Tran
			--print @sql
			Insert Into Admin.dbo.DataLenStats_Alt
			exec(@sql)
		Commit Tran
	FETCH NEXT FROM datalens_cursor
		INTO @table, @column;
	END
 
	CLOSE datalens_cursor
	DEALLOCATE datalens_cursor
	--Checkpoint
	Use Tempdb;
	Checkpoint
	'
EXEC (@sql1)
FETCH NEXT FROM dbfetch INTO @dbname;
PRINT @sql1
END
 
CLOSE dbfetch
DEALLOCATE dbfetch

And yeah, I rushed through this to get it finished up quickly.  I hope to have more time to delve into it later.  At least with this script, I can load a table with adequate data to be able to generate histograms on the data length/size distribution and then make appropriate sizing decisions based on the statistics.  Be warned – though automated it is slow and should not be run on a production server.

T-SQL Tuesday #012 – Skills

Comments: No Comments
Published on: November 2, 2010

November is upon us and in some areas this also means that the leaves have changed color.  With the change in leaves we also have a change in TSQL Ones…err Tuesday this month.  The change is with good reason as well.  November is a busy month in the DBA world.  PASS is holding the Summit Nov 8 – 11 in Seattle (that involves the second Tuesday).  We have Connections this week in Las Vegas (despite being in Vegas, I won’t be there due to budgetary constraints).  And we have Paul Randal (Blog | Twitter) hosting TSQLTuesday this month.

Paul has chosen the topic of “why are DBA skills necessary?”

You know, like nunchuku skills, bow hunting skills, computer hacking skills…

Oh wait, maybe I do have some of those computer skills.  I don’t have nunchuku skills though, and that could be useful from time to time.

As a DBA, we occasionally have the opportunity of attracting a new client or a new job or a new database.  It seems that more often than not, some of the skills requisite (at least they should be) of owning a database are missing.

Some of these include:

Backup and recovery of a database
Indexing
Disaster Recovery
Normalization and De-normalization
Performance Tuning
Server Patching
Proper Storage recommendations
De-fragmentation
File and Filegroup Creation
Performance Troubleshooting
User and Database Security
And more…

And more…

I want to touch on some of the other skills of a DBA.  These are the skills that a DBA must use in order to be successful (besides knowing the craft).  For me, these skills help make the job just a bit easier and they seem to be present in many of the top tier Database Professionals.  For me, these skills include:  Communication, Participation, Sense of Community, and Drive.  These may also appear as attributes – but I think they are things that a professional can work on and improve on to improve in the work place.

Communication

This is a skill employed in many different ways in the profession.  Many have chosen to communicate via blogs and via speaking at events, while others have written books.  This skill is a must have in the day to day business and helps to mend fences between DBA and business as well as DBA and Development.  Learning how to interact with both the positive as well as the harsh feedback is critical to career growth.

Participation

As a database professional, it is essential to be involved in meetings and the decision making process.  Just being present does not always mean that you are participating.  Are you engaged in thought of getting out of the meeting or about the next level on Angry Birds?  Or are you listening, taking notes (if necessary), and interjecting comment that is constructive to the meeting?  When a task comes across your desk, what is your reaction?  Do you just do it or do you interface with the requester to ensure that the request meets the needs?  Occasionally it will happen that the requirements do not reflect the true need from the person making the request.  Without talking to that person, a level of frustration is accomplished when you return to them having completed the request but not having fulfilled the underlying needs.

Sense of Community

One of the best networks available to use is the social network for the Database Professional.  There is a good amount of people always willing to help via twitter (#sqlhelp) and online forums (sqlservercentral.com).  A good DBA knows his/her limits and knows that they don’t know everything.  Admit it early and be willing to rely on the community when you don’t know something.  Part of being a good database professional is knowing where to find help and where to find the answer.  This also ties in with the communication skill.  There is no need to memorize every nook and cranny of SQL Server.  Learn how to take notes, create documentation, and how to talk to the community.  This will help you learn more about SQL as well as help you build friendships.

Drive

This one is a lot more difficult.  A skill that is helpful in being a better Database Professional is an internal motivation to be better and to create a better database environment no matter the employer or project.  If this means longer hours or making significant changes – then do it.  Sometimes it also means that we need to make a list and present the good with the bad of the environment and then make suggestions on how to improve.  If you are really good and don’t put in any extra effort – imagine how good you could be should you dedicate a few extra hours here and there to becoming a better Database Professional.

Oh and the other stuff

I don’t want to completely ignore those important skills.  There are many accidental DBA’s out in the world due to a database having come into existence.  Many times a database can exist without a DBA due to various variables such as vendor support, little to no activity, or low criticality of the data.  Many times one of these databases eventually explodes into being much more than initially planned (high transaction or high criticality or even reduced vendor support).  At this point a DBA is needed.  DBA’s help protect the data and are an investment for the company.  A DBA can help provide timely information as well as protect the data and ensure business continuity.  For me, it is a worthwhile investment – and not just because I do the work.

In Conclusion

Today is Election Day throughout the United States.  Get out and Vote!

There are elections at SQLServerPedia, SQLRally and then there are also the political elections.

October 2010 TSQL Tuesday Reminder

Tags:
Comments: 1 Comment
Published on: October 6, 2010

Holy Cow, another month has flown by without much of  a hint.   We now have upon us another TSQL Tuesday.  If you hadn’t heard or haven’t seen the twitter announcement, you can find it to be hosted by Sankar Reddy (Blog).  The theme this month is all about myths (this should be a fun one).  There are plenty of myths to go around, so get your myth and debunk it this month as a part of the Blog Party.

Oh and by the way, the Party is Oct 12th.

TSQL Tuesday Indexes and Blobs

Comments: 1 Comment
Published on: September 14, 2010

Woohoo – chugga chugga chugga chugga – woo woo.  The train is pulling into town once again for another installment in the TSQLTuesday Blog party.  Michael Swart is hosting and has asked us to post something ado about indexes.

What to do What to do

I thought long and hard about the topic this month.  I really wanted to discuss something that would be of use.  I also wanted to talk about something that may not have been covered by somebody else.  The topic of indexes and combination of blog entries this month should be comprehensive and covering in many aspects of Indexes.  We all know that there are Clustered Indexes and Non-clustered indexes, and then the other subtypes of indexes that I am sure have been covered by others in this party.

Then it hit me.  One day while helping in the forums I ran across a post requesting information about how to find what columns were LOB columns in the database.  I knew I had some past blog posts about various aspects of LOBs, but I had never broken it down to find the columns in the LOB.  Even better was that I wanted to know what columns were in what index that were also a BLOB.  Oooohh, spine tingling idea – I could cover Blob Index Columns.

Restore from Backup

Not really, but every once in a while we have to dig back in the backups to recover data from the past.  I had to pull up an article from the past in order to get to the script that would benefit me in this venture.

Before I go to lengths to post that script, let’s start with the script that was provided as a response to that initial question.  This is a straight-forward script that provides the answer to the question posed.

SELECT OBJECT_NAME(c.OBJECT_ID), c.name, t.name
  FROM sys.columns c
    INNER JOIN sys.types t ON c.user_type_id = t.user_type_id
  WHERE t.name IN ('text','ntext','image','xml')
    OR (t.name IN ('varchar','nvarchar','varbinary') AND c.max_length = -1)
    And OBJECTPROPERTY(c.OBJECT_ID,'ismsshipped') = 0

And here is the script that I thought could prove useful for this situation:

DROP TABLE #indstats
 
CREATE TABLE #indstats (
	indstatsid INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
	,database_id BIGINT
	,OBJECT_ID BIGINT
	,index_id BIGINT
	,IndexSizeMB DECIMAL(16,1)
)
 
INSERT INTO #indstats (database_id,OBJECT_ID,index_id,IndexSizeMB)
	SELECT database_id,OBJECT_ID,index_id
		,CONVERT(DECIMAL(16,1)
		,(SUM(ps.avg_record_size_in_bytes * ps.record_count) / (1024.0 * 1024))) AS IndexSizeMB
	FROM sys.dm_db_index_physical_stats(DB_ID(),null,NULL,NULL,'DETAILED') ps
	GROUP BY database_id,OBJECT_ID,index_id
;
 
SELECT FileGroupName = FILEGROUP_NAME(a.data_space_id)
	,TableName = OBJECT_NAME(p.OBJECT_ID)
	,p.OBJECT_ID
	,IndexName = i.name
	,LOBUsedPages = a.used_pages
	,LOBTotalPages = a.total_pages
	,LOBDataSizeMB = a.used_pages * 8/1024
	, ps.IndexSizeMB
	, (us.user_seeks + us.user_scans + us.user_lookups) AS UserRequests
	, (us.user_updates) AS UserUpdates
	, us.last_user_update AS LastUpdate
	, CAST(us.user_seeks + us.user_scans + us.user_lookups AS REAL)
		/ CAST(CASE us.user_updates WHEN 0 THEN 1 ELSE us.user_updates END AS REAL) AS RatioRequestsToUpdates
	,a.type_desc AS AllocUnitType
	FROM sys.allocation_units a
		INNER Join sys.partitions p
			ON p.partition_id = a.container_id
			And a.type = 2					--LOB data is stored in pages of type Text/Image
		LEFT Outer Join sys.dm_db_index_usage_stats us
			ON us.OBJECT_ID = p.OBJECT_ID
			And us.index_id = p.index_id
			And us.database_id = DB_ID()
		LEFT Outer Join #indstats ps
			ON us.index_id = ps.index_id
			And us.database_id = ps.database_id
			And us.OBJECT_ID = ps.OBJECT_ID
		LEFT Outer Join sys.indexes i
			ON i.OBJECT_ID = p.OBJECT_ID
			And i.index_id = p.index_id
	WHERE OBJECTPROPERTY(p.OBJECT_ID,'IsMSShipped') = 0
		--And a.data_pages > 0
		--And filegroup_name(a.data_space_id) = 'Primary'
UNION
SELECT FileGroupName = FILEGROUP_NAME(a.data_space_id)
	,TableName = OBJECT_NAME(p.OBJECT_ID)
	,p.OBJECT_ID
	,IndexName = i.name
	,LOBUsedPages = a.used_pages
	,LOBTotalPages = a.total_pages
	,LOBDataSizeMB = a.used_pages * 8/1024
	, ps.IndexSizeMB
	, (us.user_seeks + us.user_scans + us.user_lookups) AS UserRequests
	, (us.user_updates) AS UserUpdates
	, us.last_user_update AS LastUpdate
	, CAST(us.user_seeks + us.user_scans + us.user_lookups AS REAL)
		/ CAST(CASE us.user_updates WHEN 0 THEN 1 ELSE us.user_updates END AS REAL) AS RatioRequestsToUpdates
	,a.type_desc AS AllocUnitType
	FROM sys.allocation_units a
		INNER Join sys.partitions p
			ON p.hobt_id = a.container_id
			And a.type = 3					--Overflow data is stored in pages of type Text/Image
		LEFT Outer Join sys.dm_db_index_usage_stats us
			ON us.OBJECT_ID = p.OBJECT_ID
			And us.index_id = p.index_id
			And us.database_id = DB_ID()
		LEFT Outer Join #indstats ps
			ON us.index_id = ps.index_id
			And us.database_id = ps.database_id
			And us.OBJECT_ID = ps.OBJECT_ID
		LEFT Outer Join sys.indexes i
			ON i.OBJECT_ID = p.OBJECT_ID
			And i.index_id = p.index_id
	WHERE OBJECTPROPERTY(p.OBJECT_ID,'IsMSShipped') = 0
		--And filegroup_name(a.data_space_id) = 'Primary'
		--And a.data_pages > 0

That script can be found in my post here.

With that script in hand I figured a few short customizations could prove useful to help find the additional column info.  Now, I must admit, this is still a work in progress for which I want to tune it and tidy up the script substantially – where possible.  My point for now is the concept of using it to retrieve the indexed columns that are blobs and to see that extra detail about it.

I am going to make a few modifications that include adding a CTE, as well as adding the following snippet to both sides of the union, as well as a few additional columns.

LEFT Outer Join sys.index_columns ic
			ON i.index_id = ic.index_id
			And i.OBJECT_ID = ic.OBJECT_ID
		LEFT Outer Join sys.columns c
			ON ic.OBJECT_ID = c.OBJECT_ID
			And ic.column_id = c.column_id

This is what I came up with:

CREATE TABLE #indstats (
	indstatsid INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
	,database_id BIGINT
	,OBJECT_ID BIGINT
	,index_id BIGINT
	,IndexSizeMB DECIMAL(16,1)
)
 
INSERT INTO #indstats (database_id,OBJECT_ID,index_id,IndexSizeMB)
	SELECT database_id,OBJECT_ID,index_id
		,CONVERT(DECIMAL(16,1)
		,(SUM(ps.avg_record_size_in_bytes * ps.record_count) / (1024.0 * 1024))) AS IndexSizeMB
	FROM sys.dm_db_index_physical_stats(DB_ID(),null,NULL,NULL,'DETAILED') ps
	GROUP BY database_id,OBJECT_ID,index_id
;
 
WITH LOBCols AS (
SELECT FileGroupName = FILEGROUP_NAME(a.data_space_id)
	,TableName = OBJECT_NAME(p.OBJECT_ID)
	,p.OBJECT_ID
	,IndexName = i.name
	,ColumnName = c.name
	,c.column_id
	,LOBUsedPages = a.used_pages
	,LOBTotalPages = a.total_pages
	,LOBDataSizeMB = a.used_pages * 8/1024
	, ps.IndexSizeMB
	, (us.user_seeks + us.user_scans + us.user_lookups) AS UserRequests
	, (us.user_updates) AS UserUpdates
	, us.last_user_update AS LastUpdate
	, CAST(us.user_seeks + us.user_scans + us.user_lookups AS REAL)
		/ CAST(CASE us.user_updates WHEN 0 THEN 1 ELSE us.user_updates END AS REAL) AS RatioRequestsToUpdates
	,a.type_desc AS AllocUnitType
	FROM sys.allocation_units a
		INNER Join sys.partitions p
			ON p.partition_id = a.container_id
			And a.type = 2					--LOB data is stored in pages of type Text/Image
		LEFT Outer Join sys.dm_db_index_usage_stats us
			ON us.OBJECT_ID = p.OBJECT_ID
			And us.index_id = p.index_id
			And us.database_id = DB_ID()
		LEFT Outer Join #indstats ps
			ON us.index_id = ps.index_id
			And us.database_id = ps.database_id
			And us.OBJECT_ID = ps.OBJECT_ID
		LEFT Outer Join sys.indexes i
			ON i.OBJECT_ID = p.OBJECT_ID
			And i.index_id = p.index_id
		LEFT Outer Join sys.index_columns ic
			ON i.index_id = ic.index_id
			And i.OBJECT_ID = ic.OBJECT_ID
		LEFT Outer Join sys.columns c
			ON ic.OBJECT_ID = c.OBJECT_ID
			And ic.column_id = c.column_id
	WHERE OBJECTPROPERTY(p.OBJECT_ID,'IsMSShipped') = 0
		--And a.data_pages > 0
		--And filegroup_name(a.data_space_id) = 'Primary'
UNION
SELECT FileGroupName = FILEGROUP_NAME(a.data_space_id)
	,TableName = OBJECT_NAME(p.OBJECT_ID)
	,p.OBJECT_ID
	,IndexName = i.name
	,ColumnName = c.name
	,c.column_id
	,LOBUsedPages = a.used_pages
	,LOBTotalPages = a.total_pages
	,LOBDataSizeMB = a.used_pages * 8/1024
	, ps.IndexSizeMB
	, (us.user_seeks + us.user_scans + us.user_lookups) AS UserRequests
	, (us.user_updates) AS UserUpdates
	, us.last_user_update AS LastUpdate
	, CAST(us.user_seeks + us.user_scans + us.user_lookups AS REAL)
		/ CAST(CASE us.user_updates WHEN 0 THEN 1 ELSE us.user_updates END AS REAL) AS RatioRequestsToUpdates
	,a.type_desc AS AllocUnitType
	FROM sys.allocation_units a
		INNER Join sys.partitions p
			ON p.hobt_id = a.container_id
			And a.type = 3					--Overflow data is stored in pages of type Text/Image
		LEFT Outer Join sys.dm_db_index_usage_stats us
			ON us.OBJECT_ID = p.OBJECT_ID
			And us.index_id = p.index_id
			And us.database_id = DB_ID()
		LEFT Outer Join #indstats ps
			ON us.index_id = ps.index_id
			And us.database_id = ps.database_id
			And us.OBJECT_ID = ps.OBJECT_ID
		LEFT Outer Join sys.indexes i
			ON i.OBJECT_ID = p.OBJECT_ID
			And i.index_id = p.index_id
		LEFT Outer Join sys.index_columns ic
			ON i.index_id = ic.index_id
			And i.OBJECT_ID = ic.OBJECT_ID
		LEFT Outer Join sys.columns c
			ON ic.OBJECT_ID = c.OBJECT_ID
			And ic.column_id = c.column_id
	WHERE OBJECTPROPERTY(p.OBJECT_ID,'IsMSShipped') = 0
		--And filegroup_name(a.data_space_id) = 'Primary'
		--And a.data_pages > 0
 
)
 
SELECT L.column_id,L.FileGroupName,L.TableName,L.IndexName,L.ColumnName,L.LOBUsedPages,L.LOBTotalPages,L.LOBDataSizeMB,L.IndexSizeMB
		,L.UserRequests,L.LastUpdate,L.RatioRequestsToUpdates,L.AllocUnitType,t.name
	FROM LOBCols L
		INNER Join sys.columns c
			ON c.OBJECT_ID = L.OBJECT_ID
			And c.column_id = L.column_id
		INNER Join sys.types t
			ON t.user_type_id = c.user_type_id
	ORDER BY L.TableName ASC,L.AllocUnitType

This script will not return as many rows as the first script shared.  That should be an indicator that not all LOB columns are in an index.  Here we are looking for those that may be causing an extra performance impact due to the inclusion in an index.  It is always good to know what is going on in a database.  Something like this is very helpful for the newly hired DBA when trying to get to understand the databases which need to be supported.  This is also helpful when the need is to document a database.  This script may also spit out multiple rows for the same column in the same index.  This is due to that column being split into two different allocation unit types.  I feel this is good to know as well.

Here we can see just a small sample of the output from this script.

This little snippet is from a CRM database, and you can see that the clustered index in this image has three columns in it that are BLOBS and they are all three being stored as an LOB_Data allocation unit.

Conclusion

Even though this was a quick and dirty entry on the topic, there is much to be gained from the little insight this script can provide.  I would recommend that people find out what indexes are holding that LOB data.  It’s better to know than to not know.

And I go by Indexes – not indices.  Indices for me represent more of a financial term than a logical lookup term.

TSQL Tuesday 009 Roundup

Tags:
Comments: 2 Comments
Published on: August 12, 2010

T-SQL Tuesday #009: Beach Time

I hope you enjoyed your time in the sun with your toes in the sand.  We are wrapping up this vacation with a little recap on what we learned.  There were some similarities and some differences amongst our vacationers.

I enjoyed reading the comments made this month and the methods employed by each person that came along for the party.

Without further ado, in order of submission, here is what people had to say.

Pinal Dave (Blog | Twitter | TSQLTuesday9)

Pinal teaches us that we need to stop thinking about the job when on vacation and that we don’t need to be a superhero.  He also tells us that we should keep the phone on, but use restraint.

Rob Farley (Blog TwitterTSQLTuesday9)

Rob states that “Just because you’re necessary doesn’t mean you’re important.”  He has a very good point with that.  Nobody should horde all of the information about his/her job, project or process.  Learn to share your knowledge and you will learn more in the process!!

Robert Davis (Blog | Twitter TSQLTuesday9)

SQLSoldier has let it slip that he is working on some top secret project at work away from work.  What I like about this is that he is getting beach time by doing this other project.  It is not necessarily vacation but it is a change and there is a change in project focus for the week long stints that he will be doing this.

Benjamin Nevarez (Blog | Twitter TSQLTuesday9)

Ben just returned from vacation in time to participate this month.  Ben takes us on vacation with him by sharing some of his pictures.  I think a good way to get ready for vacation is to busy one’s self looking at vacation spots. :)

Jeremy Carter (Blog | Twitter | TSQLTuesday9)

Jeremy brings up some solid points.  One of the best points is the change management piece.  Jeremy also touches on the hero mentality a bit.  I really like his closing sentence: “The real hero of the day will be missed because they are a true asset, not because the world stopped in their absence.”

Bob Pusateri (Blog | Twitter TSQLTuesday9)

Bob teaches us in his entry this month that he spends a lot of time in a science museum.  When he is out at the museum he will Delegate a team member to fill in for certain projects or aspects of work.  Bob keeps it pretty simple – Documentation and Delegation are his keys to a successful vacation.

Steve Jones (Blog | Twitter TSQLTuesday9)

Steve, with his heavy packing and all, makes sure he communicates a lot before he leaves the office.  It is fair to be available for a true emergency.  The person to whom you delegated your responsibilities should be the one to escalate to you.  Trust them to understand what a true emergency is (and hopefully you won’t have to train them further on the topic when you return).

Andy Lohn (Blog | Twitter TSQLTuesday9)

There are a few things that are new in this blog from SQLQuill.  One, I like his avatar – pretty cool.  His blog theme looks good – the theme works well for his site.  Anyway, back to the topic.  When Andy leaves for vacation he sends a meeting request to the team.  No reminder is set, just a meeting request that shows the time as available.  Then he blocks it out on his calendar as out of the office with an out of office rule set.  Then he goes through his lists and checks off everything that needs to be done (knowledge transfer, tasks, etc).

Stef Bauer (Blog Twitter TSQLTuesday9)

Stef was also on vacation as the announcement went out for this months meme.    Stef works in a small shop and is available to the manager should an emergency arise.  Stef recommends a technology silence in order to enjoy vacation – thus twitter goes bye-bye.  Stef also double-checks processes prior to leaving to make sure everything is in tip-top shape.

Josh Feierman (Blog Twitter TSQLTuesday9)

This is the first ever TSQLTuesday post by Josh.  Welcome to the party Josh!  Josh believes in project visibility (that’s a good thing).  With everything up to date in sharepoint, he feels a lot more comfortable taking off for vacation.  He also makes certain that he is unreachable via email.  He will turn off email synchronization to the Blackberry when on vacation.  I am strongly considering doing the same.

John Racer (Blog Twitter TSQLTuesday9)

John believes that a system that requires constant hand-holding by the dba are incorrectly designed.  There are tools available for making your life easier – use them.  Systems should be built with ease of maintenance in mind.  This is a valuable asset.  Just because it took you 5000 lines of TSQL to accomplish what somebody could do in 10 lines, does not make your code any better or valuable to the company.

My Entry (Twitter | TSQLTuesday9)

I talk about some recent experiences around trying to get away from work for an extended weekend.  I had a funeral to attend that interfered with deadlines for work that I needed to meet.  I also talk about Beach Time as a state of mind rather than a destination or even being vacation.

That’s a Wrap

I hope you enjoyed this vacation filled week.  Let us all wrap things up with a feast in honor of a good vacation and a toast to many great accomplishments.

I hope to see you all next month for another round of TSQL Tuesday!

R & R

Comments: 4 Comments
Published on: August 10, 2010

It is once again time for the blog party known as TSQL Tuesday.  I am hosting this month and wanted to also participate.  The theme is “Beach Time” and this is TSQL Tuesday #9.  Why did I choose this theme?  There are a few reasons for it.  1.)  There are numerous people in the community getting ready, or who have recently, to change jobs.  2.)  I was on the tail end of a mini-vacation / long weekend when I got the invite to host.  3.)  To be able to take a day off for that long weekend, I wanted to make sure the loose ends were wrapped up so I would not need to work over the weekend.  4.)  The song lyrics I mentioned in the Theme announcement, were stuck in my head and reminded me of vacation.  For this post, I want to cover what Beach Time means for me and some of the things I did recently in order to get a little R & R.

Beach Time

Beach Time means having peace of mind, for me.  I can’t go on vacation if there is doubt or concern about any of my projects (work, home, financial).  So, in order for me to truly have a vacation – Beach Time comes first.

I find it completely useless to go on vacation if I am going to be checking email or project statuses every 10 minutes.  There is no rest or relaxation in doing those things while I am supposed to be doing something else.  Vacation should be fun and enjoyable.  Thus, if I am to enjoy vacation, I need to do a few extra things in the office prior to leaving.

Going the Distance

When Adam (Blog | Twitter) asked me to host, I was on my little mini-vacation.  In order to get to that vacation, I had to prep myself and work for the one day absence.  I had to make sure I had built up a few things.

1.  Confidence

2.  Skills

3.  Processes

4.  Automation

Let me explain what I mean by each of these items.  I am sure it seems a bit odd to hear that Confidence and skills must be built right before one takes a vacation.

I needed to build confidence in processes and systems that were recently deployed.  This required more testing and monitoring of the processes to ensure all would be well.  I worked on transferring some knowledge of specific items to team-members.  I wanted to make sure they knew what they were doing.  I also wanted them to know that they knew what they were doing and that they could do it.  This goes hand in hand in number one, all while building skills.  With the massive changes that we were wrapping up (complete network migration), some new processes needed to be developed and implemented.  We are using new technology and software and the old methods just didn’t work anymore or were unreliable in the first place.

In addition to these items, there was the work tasks that needed to be completed.  Since we were trying to finish the project by the weekend that I needed to be out of the office, I needed to have my tasks done that much sooner.  This meant a willingness to work longer days (ok, continue working longer days)  and try to work a little faster without making any mistakes.  This also required some increased communication and visibility with regards to the tasks and effort.

I also had a feeling that something might come up on the day I was scheduled to be out of the office.  I suspected that there may be a user request for a data dump.  In preparation for this, I also built an SSIS package that would handle the most common requests from this particular user.  The package would be able to handle various different types from this user based on common requirements I had seen in the past.  A user would only need to change a few input variables and run the package.  The result as a simplified version of a process I had been using for that particular user and was something that I could hand off to a team-mate.  This automation made it so less time could be spent on teaching the team-mate what may be needed, and permits one to just execute the package.  This was something that I wanted to get done at some point in the future anyway, but this was a very good time to introduce it into the mix.  Overall time savings of this implementation could be a couple of hours a week.  Overall savings in thought process, memory tracing, note tracing, and stress was substantial.  It was well worth the day or so that I put into creating it.

“Toes in the Water…”

Now that I have been able to accomplish some very good stuff by putting in the extra effort, I can relax a bit.  By planning ahead, communicating, working extra, and training – I can have that Beach Time that I wanted.  I was able to have the peace of mind needed to really take a vacation.  Taking a break from work sometimes requires going the extra mile just before the break happens, but it is well worth it if you don’t have to think about work at all while on vacation.

TSQL Tuesday Coming Up

Tags:
Comments: 1 Comment
Published on: August 3, 2010

The next TSQL Tuesday is only 1 week away.  This month the topic covers getting a little R&R.  We would like to know some of the things that you do in order to get the much deserved R&R.  Even if R&R means that you are changing jobs and you need to have peace of mind knowing that you were honorable in what you left behind for the replacement.

You can read more about this months topic in my blog on the topic (I am the host this month).  You can read all about it here.  After reading about it, write something up and submit your entry.

Have fun writing your entry this month and be sure to share it.

Thanks

Jason

T-SQL Tuesday #009: Beach Time

Categories: News, TSQL Tuesday
Tags:
Comments: 21 Comments
Published on: August 3, 2010

T-SQL Tuesday #009: Beach Time

Congratulations!  You have been chosen as a finalist in the Vacation Getaway package of a lifetime.  You will be flown to a resort destination of your choosing.  For this vacation, we only ask that you leave your cell-phone, laptop, twitter and facebook behind.  You have earned a break from the emergency Database repair calls and the urgent last-minute report requests.  To take advantage of this opportunity to put your “toes in the water and ass in the sand” and to feel like there’s “Not a worry in the world” and “life is good today,” just share what you did to earn it! (Lyrics courtesy of “Toes” by the Zac Brown Band)

What do you do as a DB professional to earn a little “Beach Time?”  What do you do prior to “Beach Time” to ensure that the beach time will not involve work?  The topic for this installment in TSQL2sday is to write about what you have done to be able to get a break from the job.  Beach time is usually vacation time, but is really anything that can create a break in the work-place.  If you automated a process to lighten your load – tell us about that process.  If you had to pull a 72-hr shift to ensure that your vacation plans would be unaltered by work – tell us about it.  If you turn off the cell-phone and pager and ignore email for that vacation – tell us about it.

To participate your post must go live between 00:00:00 GMT on Tuesday the 10th of August and 00:00:00 GMT on Wednesday the 11th.  Get your post in on time and I will be seeing you at the Beach!

Here’s a Few Words from the Resort Director

T-SQL Tuesday is the brain child of Adam Machanic (Blog|@AdamMachanic). Adam bestows the honor of hosting T-SQL Tuesday upon one lucky blogger each month. The guest host gets to pick that month’s topic. The top bloggers from around the globe don their dancing shoes and gather together for a blog party I’m calling the big dance-off.

If you would like to host, here’s how in Adam Machanic’s own words:

Although anyone can join in the party, hosting has a slightly higher bar: Your blog must have been active in the last six months (“active” is defined as at least one post per month), and you must have participated in T-SQL Tuesday events on at least two prior occasions. … The host blogger is not required to write a participating post to be included in the roundup, but is free to do so if he or she chooses. Want to host? Contact me through my blog–I’ll keep a waiting list and control it centrally so that it doesn’t devolve into anarchy too quickly.

Previous Vacation Destinations

#001 Adam Machanic asked for your favorite Date/Time tricks

#002 Adam followed up by asking for your favorite Puzzling Situations

#003 Rob Farley made the commitment with his topic: Relationships

#004 Mike Walsh asked for your input on IO

#005 Aaron Nelson asked us to report on “Reporting

#006 Michael Coles wanted to know All About BLOB

#007 Jorge Segarra invited us to his party to celebrate Summertime in the SQL

#008 Robert Davis brought a BandStand themed ruler to crack some knuckles in Gettin’ Schooled

Travel Checklist

1. Your post must go live between 00:00:00 GMT on Tuesday the 10th of August and 00:00:00 GMT on Wednesday the 11th.

2. Your post must link back to this post (by trackback or comment). I recommend not relying on the trackback, just in case.

3. Your post has to link back to the hosting blog, and the link must be anchored from the NEW LOGO (found above) which must also appear at the top of the post.

4. It is your responsibility to verify the trackback or comment appears here on this post. If you don’t see your trackback add your own comment with a link back to your T-SQL Tuesday post and it will be included in the roundup.

5. The following items are prohibited in your carry-on: Spear-Gun, Swords, gun powder, blasting caps, Ice-Pick, meat-cleaver and cross-bows.

Recommended, but not required:

1.       The title of your post does not need to include a reference to T-SQL Tuesday, but it is recommended.

2.       A lot of the T-SQL Tuesday bloggers and bloggees are on Twitter. Follow the hashtag #TSQL2sDay and when your post goes live, tweet a link to it with that tag.

Gettin’ Skewled

Observe and Report

This month we get to frolic in our memories of school days.  Thanks to HeadMaster Robert Davis (Blog | @SQLSoldier), we are entreated to a little detention while we figure out how we best learn.  I don’t have any idea how to learn in detention so I skipped out and headed to a more convenient place to think about learning.  I won’t share that location since I don’t want the truant officers showing up to haul me back to detention hall.

We were given a whole lot of restriction on this topic.  I am going to take a much broader approach with the topic since the topic applies to so many facets of being a SQL professional.  I will try to entreat each of the options that were listed out in the TSQL2SDAY invite by Robert Davis.

  1. How do you learn?
  2. How do you teach?
  3. What are you learning or teaching?
  4. Coup de gras post – Learn something new and Tell us about it.

I will try to answer each of these topics through one common theme with two principles “Observe and Report.”

How do you learn?

For me, learning actually comes in a lot of ways.  I think the most prevalent is through observing others.  Frankly, the term observing could be taken rather broadly or more acutely.  I think of observe more literally in the sense that I witness something and pay close attention to it.  At least I try to pay close attention.

Some times I may see something that appears like it is a good thing to know, but only witnessed it from a cursory perspective.  When that happens, I try to re-encounter the event so I can observe it more specifically.

When there is close attention to detail for such an event, it sticks just a little better.  To make the learning more permanent, one needs to practice that observation.  (It is starting to sound a little like the scientific process here.)  After I have observed such an event that requires my attention, I will try to implement it in some fashion.  Reproduce whatever it was supposed to be learned.  This will breed a higher level of consistency as well as knowledge permanence.  To bring us to the next level and internalize the learning even further, one must teach the principle or at least share it so somebody else can learn.

How do you teach?

The answer to this question is simple – It Depends.  The situation should help to determine the method.  Sometimes it may just require that a demonstration be performed.  Others may require explaining the lesson to be learned in various forms.  While yet others may require that some hands-on time be done.

I was taught that you don’t truly know the topic until you have taught it.  It is when you teach or share with somebody else that you internalize the lesson the most.  That isn’t to say that you know the topic perfectly and can answer any and all questions on the topic.

Who dares to teach must never cease to learn.  ~John Cotton Dana

As an IT professional / DBA, it is imperative that one learn all the time.  When one gives back by teaching others what s/he has learned – one learns considerable more and also becomes more respected.  The skills that pertain to being a DBA become more apparent and one is able to perform the duties associated with the job more easily.

What am I learning or teaching?

Now the questions start to get a bit harder.  It is a bit harder, in that most of what I learn professionally these days I try to share what I learn on my blog – at least what I learn professionally.  A lot of what I am learning lately is merely along the lines of troubleshooting Windows 7 to make things work as they should.  There have been quite a few nuances learned.  Now if only I could learn how to fix the USB keyboard bug in Win 7.

One of the best things I learned recently involved playtime with my children.  This is one of those things that can be learned over and over again.  It involves the little things that can help bond a relationship between parent and child.  A little game of hide and seek with one child soon turned into a rambunctious festival with my three youngest children and wife.  We played hide-n-seek for hours inside the house.  The kids were the  seekers all day and the adults hid.  It was a lot of fun and we got to teach the kids what family is about.  They enjoyed it and I hope they will do the same with their children some day.

I would also like to add that I am learning how much more important it is to Observe and Report.  These particular principles apply in so many facets of life.  Whether it be family, religion, politics or business – there is always a requirement that Observations be made and that you Report back to somebody about something.  Reporting is such a key component of everyday life and is often-times over-looked.  The method for reporting is not as important as the fact that it be done.  Reporting could be as simple as recounting a story to a friend or family member.  Reporting can often times be used as the method to teach or vice-versa.  Take the play time example I shared.  I will write that in my journal and then read some day in the future.  That will spark a memory and then I will talk with my children about it and spark a memory for them.  This story will serve as a form of report (as will the journal and blog entry now) that can be used many times over to teach this lesson.

Coup de Gras

There are learning opportunities everywhere.  A very recent reminder of this was a business lesson I just learned from the NBA.  Many may of heard of the recent backlash by the owner of the Cleveland Cavaliers concerning recent free-agent signings.  The lesson is that emotions can get the better of people in certain circumstances but we must learn to reign them in and behave professionally when in public.  Despite the belittlement and lack of integrity by one side, the other was able to maintain a good amount of integrity.

I am learning that learning is not just formalized education in a classroom or in specific settings.  There are things to be learned from all aspects of life.  This can be learned if only a little observation is used.  When you learn something, return and report what you have learned to a friend, family member, co-worker or somebody that could use it.

Data Compression

We have come to that time of month again – blog party.  This time, the party is hosted by Jorge Segarra (aka SQLChicken) (Blog | Twitter).  The rules have also changed this month, though ever so slightly.  Now, we must insert a pic into our blog post rather than include the TSQL Tuesday in our blog title.  BTW, this month we are discussing features in SQL 2008 (supposed to be R2, but I am only discussing something that came out with 2008).

Pick your Poison…err Feature.

The feature that I have chosen is compression.  In SQL 2008 we have the option to compress backups as well as compress the data.  The data can be compressed in two methods as well.  I will just be discussing my experience with Page level compression.  I will touch lightly on the differences between row level and page level compression.

History

Do you recall a nifty utility that Microsoft gave us back in the glory days called Doublespace that was later renamed to Drivespace?  I do!!  Oh the memories are painful still.  That little compression agent was renamed due to the inaccuracy of the name.  You didn’t truly get double the space on your hard drive by using it.  I remember numerous support calls related to compression and all of them turned out ugly.  Something about compressing your drive and then losing everything because you used a Drive Overlay to access a larger disk drive than the BIOS supported and then used Doublespace to compress it.  Or another good one was to lose the doublespace bin files from a compressed drive.  You could also see heavy fragmentation issues.  All of these have created a heavy bias for me against mass compression utilities.

Ch Ch Ch Changes

Despite my heavy bias against compression, I have always like the ability to compress selectively certain files or folders.  The reasons for compressing in this method, for me, have largely been for archival purposes.  There are several file compression utilities out there on the market for use in performing this.

How does that relate to database compression?  I see database compression, as offered with SQL 2008, to be more like these file compression utilities than DriveSpace.  Data compression in SQL 2008 is not an all or none implementation.  You get to pick and choose what gets compressed.  That is a big time bonus for me.

The Setup

After some research and having learned a bit about compression, I decided to test it out.  I have yet to test performance as I have only tested the disk savings that compressing could generate.  There is a good demonstration on performance by Jason Shadonix here, for those that are interested.  I will be baselining and testing performance at a later time – that is just a bit beyond the scope for this article.

I decided to use a database from our warehouse that resides on SQL 2000, on Windows 2003 32 Bit, currently.  I created a backup of that database and restored it to a test box that is running SQL 2008 on Windows 2008 R2 64 Bit.  The starting database size was 164GB.  The database was also left in SQL 2000 compatibility mode.  The selection criteria for tables to compress was to select any table larger than 1GB in size.  I used a script I showed in the table space series to determine which tables to target.  The script can be found as follows.

DECLARE @dbsize DECIMAL(19,2)
		,@logsize DECIMAL(19,2)
 
SET NOCOUNT ON
 
/*
**  Summary data.
*/
BEGIN
	SELECT @dbsize = SUM(CONVERT(DECIMAL(19,2),CASE WHEN type = 0 THEN SIZE ELSE 0 END)) * 8/1024
		, @logsize = SUM(CONVERT(DECIMAL(19,2),CASE WHEN type = 1 THEN SIZE ELSE 0 END)) * 8/1024
		FROM sys.database_files
 
END
/*
**  We want all objects.
*/
BEGIN
	WITH FirstPass AS (
		SELECT OBJECT_ID,
			ReservedPage = CONVERT(DECIMAL(19,2),SUM(reserved_page_count)) * 8/1024,
			UsedPage = CONVERT(DECIMAL(19,2),SUM(used_page_count)) *8/1024,
			PageCnt = SUM(
			CONVERT(DECIMAL(19,2),CASE
				WHEN (index_id < 2)
					THEN (used_page_count)
				ELSE lob_used_page_count + row_overflow_used_page_count
				END
			)) * 8/1024,
			RowCnt = SUM(
			CASE
				WHEN (index_id < 2)
					THEN row_count
				ELSE 0
			END
			)
		FROM sys.dm_db_partition_stats
		--Where OBJECTPROPERTY(OBJECT_ID,'IsMSShipped') = 0
		GROUP BY OBJECT_ID
	)
	,InternalTables AS (
		SELECT ps.OBJECT_ID,
			ReservedPage = CONVERT(DECIMAL(19,2),SUM(reserved_page_count)) * 8/1024,
			UsedPage = CONVERT(DECIMAL(19,2),SUM(used_page_count)) *8/1024
		FROM sys.dm_db_partition_stats  ps
			INNER Join sys.internal_tables it
				ON it.OBJECT_ID = ps.OBJECT_ID
				And it.internal_type IN (202,204,211,212,213,214,215,216)
		WHERE it.parent_id = ps.OBJECT_ID
			--And OBJECTPROPERTY(ps.OBJECT_ID,'IsMSShipped') = 0
		GROUP BY ps.OBJECT_ID
	)
	,Summary AS (
		SELECT
			ObjName = OBJECT_NAME (f.OBJECT_ID),
			NumRows = MAX(f.rowcnt),
			ReservedPageMB = SUM(IsNull(f.reservedpage,0) + IsNull(i.ReservedPage,0)),
			DataSizeMB = SUM(f.PageCnt),
			IndexSizeMB = SUM(CASE WHEN (f.UsedPage + IsNull(i.UsedPage,0)) > f.PageCnt
							THEN ((f.UsedPage + IsNull(i.UsedPage,0)) - f.PageCnt) ELSE 0 END) ,-- Equivalent of max_record_size from sys.dm_db_index_physical_stats
			UnusedSpace = SUM(CASE WHEN (f.ReservedPage + IsNull(i.ReservedPage,0)) > (f.UsedPage + IsNull(i.UsedPage,0))
				THEN ((f.ReservedPage + IsNull(i.ReservedPage,0)) - (f.UsedPage + IsNull(i.UsedPage,0))) ELSE 0 END),
			DBSizeMB = @Dbsize,
			LogSizeMB = @logsize
		FROM FirstPass F
			LEFT Outer Join InternalTables i
			ON i.OBJECT_ID = f.OBJECT_ID
		GROUP BY f.OBJECT_ID
	)
	SELECT ObjName,NumRows, ReservedPageMB, DataSizeMB, IndexSizeMB, UnusedSpace, DBSizeMB, LogSizeMB,
			PercentofDB = ((IndexSizeMb + DataSizeMB) / @DBsize) * 100
	INTO #LargeTables2Compress
	FROM Summary
	ORDER BY PercentofDB DESC
END

In this script, you will note that I am dumping the results into a temp table.  I wanted to be able to run a few different cases against the data to check results quickly without running the entire query over again.  Though, running this particular query would not take that long in most cases.  Consider the temp table a fail-safe to prevent long execution times of the query.

To determine which tables from the previous query I would target, I employed a script similar to the following.

SELECT 'Alter Table ' + objname +' rebuild with (Data_Compression = Page);'
	FROM #LargeTables2Compress
	WHERE DataSizeMB > 1000

This is pretty straight-forward.  I am only selecting those tables from the temp table that are larger than 1 GB.  I am also concatenating a string to those tables for manual execution purposes.  I can now see which tables are “large” and compress them with Page level compression or not (note: the same sort of script would work for Row Level compression).  After, I was happy with the result set and which tables would be compressed, I proceeded with compressing the tables.  Recall that the database started at 164GB.  After compression of the handful of tables (30 versus the 460 tables in the database), the database used space was now down to 84GB.  That is a reduction of ~49% in space requirements for this database.  For me, that is a pleasing result.

What if…

Should you decided to run this process again, the tables that you have already compressed will be included in the result set.  Should you proceed with running the table alter scripts again, you will not get any better compression and the compression will remain in effect.  Or, you could eliminate those tables that are compressed by altering the script provided to also read from sys.partitions as in the following script.

SELECT 'Alter Table ' + objname +' rebuild with (Data_Compression = Page);'
	FROM #LargeTables2Compress
	WHERE DataSizeMB > 1000
		And objname in
			(SELECT OBJECT_NAME(p.OBJECT_ID) FROM sys.partitions p
				WHERE p.data_compression =0
					And OBJECTPROPERTY(p.OBJECT_ID,'ISMSShipped') = 0
					)

Conclusion

Without hard and fast numbers concerning performance, a final conclusion could not be made concerning whether to compress or not.  Having run a few dry runs to test if processes still worked, I am pleased with the performance (it is faster – I don’t have the final data to back that now though).  The disk savings and even with a stalemate on performance, I like the compression that is offered in SQL 2008.

«page 2 of 3»
Calendar
May 2012
M T W T F S S
« Apr    
 123456
78910111213
14151617181920
21222324252627
28293031  
Follow me on Google+

In 0 people's circles

Add to circlesi
Content
Categories

Categories

Now Reading

Now Reading

Planned books:

Current books:

  • ChiRunning: A Revolutionary Approach to Effortless, Injury-Free Running

    ChiRunning: A Revolutionary Approach to Effortless, Injury-Free Running by Danny Dreyer, Katherine Dreyer

  • Advanced Marathoning – 2nd Edition

    Advanced Marathoning – 2nd Edition by Peter Pfitzinger, Scott Douglas

  • SQL Server MVP Deep Dives

    SQL Server MVP Deep Dives by Nielsen Paul, Delaney Kalen, Machanic Adam, Tripp Kimberly, Randal Paul, Low Greg

  • A World Without Heroes (Beyonders)

    A World Without Heroes (Beyonders) by Brandon Mull

Recent books:

View full Library

SQLHelp

SQLHelp


Welcome , today is Thursday, May 17, 2012