Tags: 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.

TSQL Tuesday 14: Committed

Comments: 2 Comments
Published on: January 11, 2011

Woohoo, It’s TSQL Tuuuuuuuuuuuuuuuuuuesday!!! This month we are being hosted by one-half of the MidnightDBA – Jen McCown (Blog | Twitter), and she has asked us to speak on resolutions.

If we look in the dictionary we will find that resolution is closely related to several other words such as resolve and commit.  One form of resolution is the formal act of declaring your personal resolve or personal commitments.  For me, maybe it is just the act of having been committed.

More seriously – a resolution is just a fancy way of saying that you are making a personal commitment or personal goal.  As with all goals, you should track it.  Otherwise it’s not really a goal, nor is it really a strong commitment.

My Commitments

For this TSQL Tuesday post, I will just add a short list of my professional goals for this next year.  Otherwise, this post would be mostly about my non-professional goals.

This goals are nothing earth shattering.  But at least they are goals to keep me going, even with all of the other stuff still going on.

  1. Certification – I will complete my MCITP certification this year.  I wanted to do it last year, but never really focused on it or gave myself a firm deadline.
  2. Build out a Virtual Environment – this involves setting some VMs for Oracle, MySQL, FireBird, and SQL Server.  I may add other RDBMS’ to that list.  I want to use this environment to learn how to interface between them using SSIS.
  3. Public Speaking – Through brown bags, SQLSaturdays and User Groups – I want to speak more often.  I hope to do 2 SQLSaturdays (we’ll see how that pans out), 2 UG presentations, and then quarterly brown bags.
  4. Writing – I have two more articles in queue that I need to write and I want to write two beyond that for a total of four this year.  I also need to write more technical blog entries.  This has been extremely beneficial to me.  Writing in an effort to share knowledge has helped me learn the subject better.

Again, that is just a short list of goals, but it should keep me busy in addition to how busy I will be with my other goals, with life, and with family.

As I pondered these goals a bit more, I am somewhat stoked about them.  These goals will help with other goals.  These goals will help me to learn quite a bit – even though they may seem a bit generic.  I put a fair amount of thought into these and know I can achieve them, but also know that I have stepped them up a tad from last year.  I am looking forward to meeting some of you at SQL Saturdays as well as I am stoked about my Virtual Environment.

T-SQL Tuesday #13 – Business Requirements

Comments: 1 Comment
Published on: December 13, 2010

Business Requirements

We have made it yet another month and to yet another episode in the continuing saga known as TSQL Tuesday.  This month we are being hosted by Steve Jones ( Blog | @Wayoutwest ) of SqlServerCentral fame.  Steve has asked us to speak a little bit about business requirements, interpreting those requirements, and some of the pitfalls that may or may not exist in the whole communication process of getting a project done.  Now, can somebody please explain the requirements for me?

What issues have you had in interacting with the business to get your job done?

I think a common area that is easily overlooked when it comes to requirements and interpretation of requirements is report creation.  A common problem is that there are no defined or written requirements for the creation of a report.  When there are inadequate requirements, it is easy to miss the intention of the report and thus frustrate the business group that requested the report.  Another problem that can arise is the perceived inaccuracy of a report – even when all business requirements are properly met and signed off by the requesting business group.  How can that be?  Let me explain.

Perceptions

A recent problem was brought to light that revolved around the creation of two similar reports.  The reports were to be used by different business groups and each was requested by a different group.  The values in the reports no longer match due to a change requested on ReportA by GroupA.  GroupB doesn’t think this is accurate and wants both reports to match.  Small problem is that both reports should not produce the exact same results based on requirements and usage.  The report for GroupA has some extra requirements and filters placed on it to prevent the users from seeing data about former employees.  The report for GroupB is different in that it should show an overall summary for all data, even data of former employees.

Re-Alignment

Managing business requirements is almost as much about managing the perceptions of the business users as it is understanding what the business truly wants.  It is important that you are able to help them understand what it is you will be doing, what you can accomplish, when you can do it, and what impact it may have on other business parts (if they are known).  When an issue arises, it is best to approach the business and try to understand what the disconnect is.  In the case of the example of two reports outlined, I had to research and test both reports to get a better understanding of what the problem was.  Once I did that, then it was a matter of explaining the findings to the business.  From there, a discussion between business analyst and the two departments for which the reports serve needs to take place and an agreement made.

Conclusion

This is a rather short and straight-forward entry for this month for TSQL Tuesday.  This is a delicate subject and I am sure many people will have many more tales to tell.  I think it is most important to approach the business and try to help them understand what you understand from the requirements and get it hammered out before too much development has been done.

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.

A Haunting TSQL Tuesday Tale

Comments: 1 Comment
Published on: October 11, 2010

Time for the ghouls and goblins to come out of the woodwork once again for another tale of deception and tyranny.  OK maybe not tyranny but definitely a haunting tale is to be told this month while trick-or-treaters plan their routes and mend their costumes.  We have SQueeLing experts suiting up for the adult party known as TSQL Tuesday.

This month the vampires, ghosts, and zombies are all breaking it down at Sankar Reddy’s place (Blog | Twitter).  The ghoulish stories to be shared are to be myths from the underSQLworld.

Truncating a Table is Unrecoverable

Have you heard this one in the past?  If you truncate a table, you cannot undo the action like you can with a delete.  What is the difference between the two methods to remove data from a table?

When you truncate a table, the pages are deallocated with minimal locking of the resources.  When you use the delete statement, the data is deleted row-by-row with more locks.  Everybody knows that a delete can be rolled back.  Many people believe that a Truncate cannot be rolled back.

Well, at this point we really need a table to test.  So let’s create a table and perform a few simple tests.

SELECT TOP 1000000
		RollID       = IDENTITY(INT,1,1)
	INTO dbo.TruncTabRollback
	FROM Master.dbo.SysColumns t1,
		Master.dbo.SysColumns t2 
 
ALTER TABLE dbo.TruncTabRollback
	ADD PRIMARY KEY CLUSTERED (RollID)

With the test table ready to go, we will begin with the baseline demonstration on the Delete command.  Here is the script to demonstrate that a Delete can be rolled back (but we already knew that).

BEGIN TRAN delrollback
 
DELETE TruncTabRollback
 
SELECT COUNT(*) AS PreRollBack
	FROM TruncTabRollback
 
ROLLBACK TRAN delrollback
 
SELECT COUNT(*) AS PostRollBack
	FROM TruncTabRollback

Pretty simple and straight forward – baseline is proven with that script.  The premise that a Delete can be rolled back has been established.  Now, how about that truncate statement?  For the truncate statement, I will use the same simple script, substituting the appropriate commands in this script.

BEGIN TRAN delrollback
 
TRUNCATE TABLE TruncTabRollback
 
SELECT COUNT(*) AS PreRollBack
	FROM TruncTabRollback
 
ROLLBACK TRAN delrollback
 
SELECT COUNT(*) AS PostRollBack
	FROM TruncTabRollback

When this script is executed, we see that indeed the data is recoverable.  Here are the results I get from the truncate and associated rollback script.

Conclusion

I think this is one of those myths that is frequently floated throughout the SQL world due to another myth that is related to the Truncate statement.  It is often explained that you can’t recover a truncate because the truncate is not logged.  That is also obviously wrong (if it weren’t logged, how could you recover the table without a restore?).  The myth about Truncate being non-logged has already been debunked (as has this one – in a different series) by Paul Randal in his Myth-A-Day series.  The key to this is that the Truncate is logged and that you wrap the command in a transaction – and only commit when you are ready.

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.

September TSQL Tuesday

Tags:
Comments: 2 Comments
Published on: September 8, 2010

It is hard to believe that time is flying like it is.  Already it has been a month since I hosted TSQL Tuesday.  This month the party is being hosted by the Database Whisperer, Michael Swart (Blog).  We have been given the challenge to write about indexes err indices err indexes - well, you get the point.

Don’t forget to follow the hashtag (#TSQL2sday) on twitter.

I hope this helps somebody remember that the blog party is less than a week away at this point.

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.

«page 2 of 4»
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