Articles from May 2010



And Here You Thought It Just RTM’d

Blurry Bath BabyEarlier this month Microsoft launched SQL Server 2008 R2.  And then last week Microsoft release Cumulative Update 1 for SQL Server 2008 R2.  You might might be getting serious like this baby thinking, “Really, already?!”

The reality though is that this deserves a “YES!”

Why would a quick Cumulative Update after release be such a good thing?  That’s because the most recent Cumulative Updates rolls up all of the changes that were part of Cumulative Updates 4, 5, 6, and 7 for SQL Server 2008 Service Pack 1.

Rather than making us wait to find the issues related to these Cumulative Updates again, this has all been updated for us.

Happy downloading!

Doing Something About Auto Generated Names

Zombie Apocafest 2009 - Shaun & EdI like my name.  It provides a point of reference to who I am.  If I am at work and someone calls for “Jason Strate”… that’s me.  If I am at home, the same thing can happen and I still know that it’s me.  I know that no matter where I am, my name will be a constant and it means something when it is called.  Hopefully, it doesn’t mean “late to dinner”.

This same principle applies to the tables and the objects related to those tables.  We give that table a name in the development environment, maybe it’s called “ZombieBaconUnicorn”.  We expect that it will be called “ZombieBaconUnicorn”.  Unfortunately, this doesn’t always ring true with other database objects related to tables; such as Primary Keys and Defaults Constraints.

Random Naming

There are multiple ways to create Primary Key and Default Constraints and they don’t all have an implied name.  Take for instance the following script, what would you assume the names of the Primary Key and Default Constraints would be?

CREATE TABLE dbo.RandomPKandDC
(
RandomPKandDCID int IDENTITY(1,1) PRIMARY KEY CLUSTERED
,Column1 datetime DEFAULT(GETDATE())
)

SELECT name FROM sys.objects
WHERE parent_object_id = OBJECT_ID('dbo.RandomPKandDC')

Did you guess the following names?

image

No?!  Run it on you machine, you’ll get your own unique names.

Non-Random Naming

Getting around the random naming is pretty simple.  Below I’ll would you through the steps.

The first change is how you’ll define the PRIMARY KEY on the table with the CREATE TABLE statement.  Instead of adding PRIMARY KEY CLUSTERED on the column definition, add it to the table as a constraint.

CREATE TABLE dbo.NonRandomPKandDC
(
NonRandomPKandDCID int IDENTITY(1,1)
,Column1 datetime
,CONSTRAINT PK_NonRandomPKandDC_RandomPKandDCID PRIMARY KEY CLUSTERED (NonRandomPKandDCID)
)

Next you want to use the ALTER TABLE statement to add the DEFAULT CONSTRAINT.  Instead of making the default part of the column definition in the CREATE TABLE, you want to name the default as a constraint to name it as it is created.

ALTER TABLE dbo.NonRandomPKandDC ADD CONSTRAINT DF_NonRandomPKandDC_Column1
DEFAULT (getdate()) FOR [Column1]

Take a look at the results of the next query:

SELECT name FROM sys.objects
WHERE parent_object_id = OBJECT_ID('dbo.NonRandomPKandDC')

image

On your server and mine the objects will have the same name.  When you deploy objects build from T-SQL like this from development to test to production they will have the same names.

What the!?

Now there isn’t anything wrong with these random names from the perspective of how your database will perform.  But it will hose up things such as database comparisons and investigating errors.

With database comparisons, the issue is pretty obvious.  If the contents of the object are the same but the name is different then it isn’t the exact same object.  Many tools have options for ignoring these names, but there are some that don’t.  Even when the tool has the option to ignore, you will need to rely on the operator of the tool to disable the feature.

Looking now at investigating errors, I am a big fan of errors that can tell me the problem within the database.  Which of the following is easier to understand.  The first with the random name:

Msg 2627, Level 14, State 1, Line 2
Violation of PRIMARY KEY constraint ‘PK__RandomPKandDC__5D60DB10′. Cannot insert duplicate key in object ‘dbo.RandomPKandDC’.
The statement has been terminated.

Or the second with the stated name:

Msg 2627, Level 14, State 1, Line 2
Violation of PRIMARY KEY constraint ‘PK_NonRandomPKandDC_RandomPKandDCID’. Cannot insert duplicate key in object ‘dbo.NonRandomPKandDC’.
The statement has been terminated.

Ok, maybe this isn’t the best example of this type of issue, but it does tell me exactly the issue and because I named the object explicitly I know where the problem is and something about the issue before digging into the schema of the table.

Overall, this is about reducing pain points in building and using your databases.  The easier it is to manage them once they are deployed, the more Bejeweled Blitz you can play on Facebook between your projects.

Renaming the Objects

Maybe I’ve sold you on this idea.  If so, you may be thinking “What the heck do you do with all of my existing databases objects?”  That answer is simple… rename them.  Since the names of these objects isn’t tied to how they are defined, you can easily get them renamed with sp_rename.

The following two scripts are what I use to rename PRIMARY KEY CONSTRAINTS and DEFAULT CONSTRAINTS.

This first one will provide sp_rename statements that you can execute to rename all of your PRIMARY KEY CONSTRAINTS:

;WITH PKNames
AS (
SELECT name AS IndexName
,OBJECT_NAME(object_id) AS TableName
,OBJECT_SCHEMA_NAME(object_id) as SchemaName
,(SELECT '' + c.name
FROM sys.index_columns ic
INNER JOIN sys.columns c
ON ic.object_id = c.object_id
AND ic.index_column_id = c.column_id
WHERE ic.object_id = i.object_id
AND ic.index_id = i.index_id
AND ic.is_included_column = 0
ORDER BY ic.key_ordinal
FOR XML PATH('')) AS Columns
FROM sys.indexes i
WHERE i.is_primary_key = 1
)
SELECT 'EXEC sp_rename ''' + QUOTENAME(SchemaName) + '.' + QUOTENAME(IndexName) + ''', ''PK_' + TableName + '_' + Columns + ''''
FROM PKNames
WHERE IndexName <> 'PK_' + TableName + '_' + Columns

The second one will provide sp_rename statements that you can execute to rename all of your DEFAULT CONSTRAINTS:

SELECT 'EXEC sp_rename ''' + QUOTENAME(OBJECT_SCHEMA_NAME(dc.parent_object_id)) + '.'
+ QUOTENAME(dc.name) + ''', ''DF_' + OBJECT_NAME(dc.parent_object_id) + '_' + c.name + ''''
FROM sys.default_constraints dc
INNER JOIN sys.columns c ON dc.parent_object_id = c.object_id AND dc.parent_column_id = c.column_id
WHERE dc.name <> 'DF_' + OBJECT_NAME(dc.parent_object_id) + '_' + c.name

Hopefully these can be helpful for you as well.

Conclusion

In a roundabout way, this post has been about naming conventions.  Make the world a prettier place by having a convention on naming the objects in your database.

Last word… don’t just run out and use this in your production database without doing your own testing and promoting using your own company’s deployment process.  An obvious statement but one that I thought I should point out since I know how tempting this can be.

EDIT 2010/05/27: Modified scripts to account for schema variations.

Connect Item on Import/Export Wizard

I like using raw files in SQL Server Integration Services (SSIS).  They are a quick way to build data repository that will be used else where in a package or for use with a separate package.  In a recent project, raw files were used to move client data around in a new import process that consolidated business logic and improved performance. 

As much as I like raw files, there is a place in SQL Server where the love I have for raw files is lacking.  This is with the Import/Export Wizard in Management Studio.  If you look through the wizard, you’ll find Excel love, Access love, and even some Oracle love.  But there isn’t an option to import or export raw file data.

 

Stop the Madness

Susan Powter said it best, “Stop the Madness”.  Ok, maybe this isn’t madness.  But it sure is irritating when I have to write an SSIS package from scratch to import a raw file to my sandbox database to see what data is in it that is causing issues.  If it were any other data source or destination, there wouldn’t be a need to do that extra work.

Is this extra work very hard?  No, of course not.  But this is a barrier to using this format.  I’ve been pushed away from them before when explaining the need to build a package to view raw file data.  When other formats can be imported with just a few clicks of a button.  The five to ten minutes to stop and build the package and import the data can add up in some situations.  And compating it to the minute or so to use the wizard, this can be a significant time savings when developing and testing SSIS packages.

There is certainly no sense in complaining without trying to fix.  So here it goes…

If you think this idea is kicking, special, or worthy of your support – please go out and vote up the Connect item that has been submitted on it.

TechFuse Presentation and Speaker Rankings

Last week I spoke at TechFuse 2010 and my topic was Getting to Know Your Indexes.  I thought I’d throw up a link to the presentation materials from the event.  TechFuse was a lot of fun and I got to spend some time chatting with Dan English (twitter | blog) and Lara Rubbelke (twitter | blog) about SQL Server 2008 R2.

From my session, I received some feedback and it came back a lot better than I had expected.  I hadn’t felt on my game that day and this presentation is usually pretty dry compared to others that I do.  On a scale of 1-7 I received the following scores:

  • 6.6 – Speaker(s) demonstrated expertise on the subject matter
  • 5.7 – Knowledge in this session will help me in the job role
  • 5.4 – Content delivered met my expectations
  • 5.6 – I enjoyed the subject matter

Some of the comments I received…

“A lot of useful information.”
“Good Info.”
“Lots of detail. Speaker very knowledgeable.”

If you saw me there and want to drop an additional comment, feel free to add a comment at SpeakerRate.

Also, if you saw me present on Application and Multi-Server Management at the SQL Server 2008 R2 launch event in Minneapolis I’d appreciate any feedback on that as well.

Free SQL Server Training

"Free Kitten!!! Free Kitten!!!" We all like free stuff.  Especially when we already know it’s something we love.  And if you are reading this blog, you likely love or really like SQL Server.  Or just maybe you are paid to like it.

What ever the reason, the more you know about it the better you will be in applying the features to your business issues.  Which it turn could lead to things like bonuses and a brand new car.

So speaking of free training,  Pragmatic Works, WROX, SQL Server Central, and SQL Server Magazine have gone together to provide a monthly series on SQL Server training. 

This month’s topics are:

SQL Server Parallel Data Warehousing (PDW)
Register!
May 18, 2010 11:00 a.m. EDT
Bruce Campbell, Microsoft

SQL 2008 R2 Parallel DW Appliance (PDW) – formerly known as Project Madison, PDW, is Microsoft’s first DW Appliance. PDW utilizes Massively Parallel Processing (MPP) and will scale out SQL Server 2008 R2 DW from 10’s to 100’s of TBs. PDW has standard support for MPP, High Availability, Linear Scalability and a HUB and Spoke DW Architecture.  In this session Bruce Campbell will present the underlying architecture of PDW and how Parallel processing will improve upon your current data warehousing designs.

The role of Solid State Storage (SSS) in Modern Data Warehouses.
Register!
May 20, 2010 11:00 a.m. EDT 
Sumeet Bansal

Solid State Storage (SSS) is making a significant contribution towards modern Database systems.  In this session, Sumeet will talk about the challenges that traditional storage systems pose for Data Warehouses, and how SSS can alleviate them.  He will talk about the impact of an SSS based Data Warehouse for vastly increased performance and energy efficiency.

Creating Dashboards in PerformancePoint 2010.
Register!
May 25, 2010 11:00 a.m. EDT
Mark Stacey

With the release of Sharepoint 2010, Performance Point Services has evolved into a enterprise ready rapid development dashboarding and scorecarding toolkit.

Creating KPIs, scorecards and dashboards has never been easier.

During this training session, Mark will show how to connect to disparate data sources such as Analysis Services cubes, databases, and information stored in Sharepoint lists, and present this data in scorecards and charts.

If this sounds appealing – run out and get registered at the links above.  Also, keep up to speed with upcoming sessions from the webinar page.

PASS Summit 2010 Call for Speakers

Clone Robin HoodPASS announced today it’s Call for Speakers for the 2010 PASS Summit.  This is an opportunity to share your experiences and knowledge with SQL Server Community. 

Do you have some tricks that have made your job a success that you can share?  Did you work on an interesting project with hurdles that were overcome with the use of SQL Server features?  Here is your time to shine and share what you know.

PASS is looking for sessions in the following areas:

  • Enterprise Database Administration and Deployment
  • Application and Database Development
  • BI Platform Architecture, Development and Administration
  • BI Information Delivery
  • Professional Development

But I’m Not Qualified

Do use SQL Server?  Well then you have the first necessary qualification.  If you are using it then I absolutely bet that you have learned something that at least 50 of the probably 3,500 attendees will be interested in hearing about for 75 minutes.

Will you be able stand in front of your peers and no run off?  Then you have the second qualification licked.  Many of us have thought about running off right before a presentation before – and sometimes in the middle of them.  Heck, at my second presentation I asked if they wanted me to bow out since the first gentleman had gone over his time.  I wasn’t being accommodating – I was petrified.

Yeah, but I am not as _____ as Brent, Bucky, Jimmy, Paul, Kimberly, Adam, Kalen, or Kevin.  Of course this list could on for a while.  Insert whatever adjective you want in the blank.  I’ll agree outright that neither am I.  We all have different experiences and styles and increasing the variety at the PASS Summit will only make it better.  Heck, they took me in last year.  I bet you would do just as well as I do.

I’m Not Ready For PASS

If I haven’t convinced you, but you still have an open mind.  I encourage you to present at your local user group.  If you are already doing that, then make the jump to presenting at SQL Saturday events.  SQL Saturdays are great lead ups to the PASS Summit.

Searching for Plans

70999185_58c1ad9d35

A while back I wrote a post on a procedure I created for the DBADiagnostics database that I talk about from time to time.  This procedure allowed users to search the procedure cache to find plans for procedures by database name and object name.  This had worked out pretty good until I noticed something the other day.

The procedure is using the sys.dm_exec_query_stats as the based table for the query to build itself upon.  The trouble with using this DMV is that it doesn’t have all of the plans listed from the procedure cache.  Only those that currently have stats stored for sql_handles.

About the same time I started writing this post, I noticed a post by Adam Machanic (twitter | blog) in which he puts out a warning to those using sys.dm_exec_query_stats.  In that post, he discusses how the ALTER TABLE statement can result in a batch missing this DMV.

Considering all this lends itself to the question, is there a better DMV that can be used to find plans in the procedure cache?

Use sys.dm_exec_cached_plans Instead

Another DMV that has this information in it is the DMV sys.dm_exec_cached_plans.  This DMV is designed to provide a list of all cached plans in the procedure cache.  To illustrate the difference, lets take a look at the following two queries.


SELECT COUNT(DISTINCT plan_handle)
FROM sys.dm_exec_cached_plans
GO 

SELECT COUNT(DISTINCT plan_handle)
FROM sys.dm_exec_query_stats
GO

On my system, the following results are returned:

image

The first value is the number of plan_handles in sys.dm_exec_cached_plans.  The second is the number of plan_handles in sys.dm_exec_query_stats.  There is a substantial difference between the two.  This is something you’d be expecting based on the information at the start of this post.

Query to Find Cached Plans

Now that I’ve outlined the issues with my original post, lets take a look at a script that will query the procedure cache to look for plans stored for stored procedures and other database objects.


SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
GO

DECLARE @DatabaseName sysname
    ,@ObjectName sysname 

SELECT @DatabaseName = 'msdb'
    ,@ObjectName = 'sp_jobhistory_row_limiter';

WITH PlanSearch
AS (
      SELECT qp.dbid
            ,qp.objectid
            ,DB_NAME(qp.dbid) as DatabaseName
            ,OBJECT_NAME(qp.objectid, qp.dbid) as ObjectName
            ,cp.usecounts
            ,cp.plan_handle
      FROM sys.dm_exec_cached_plans cp
            CROSS APPLY sys.dm_exec_text_query_plan(cp.plan_handle, DEFAULT, DEFAULT) qp
    WHERE cp.cacheobjtype = 'Compiled Plan'
      AND (DB_NAME(qp.dbid) = @DatabaseName OR NULLIF(@DatabaseName,'') IS NULL)
    AND (OBJECT_NAME(qp.objectid, qp.dbid) = @ObjectName OR NULLIF(@ObjectName, '') IS NULL)
)
,PlansAndStats
AS (
      SELECT ps.DatabaseName
        ,ps.ObjectName
        ,ps.usecounts -- Use in place of qs.execution_count for whole plan count
        ,CAST(SUM(qs.total_worker_time)/(ps.usecounts*1.) as decimal(12,2)) AS avg_cpu_time
        ,CAST(SUM(qs.total_logical_reads + qs.total_logical_writes)/(ps.usecounts*1.) as decimal(12,2)) AS avg_io
        ,SUM(qs.total_elapsed_time)/(ps.usecounts)/1000 as avg_elapsed_time_ms
        ,ps.plan_handle
    FROM PlanSearch ps
            LEFT OUTER JOIN sys.dm_exec_query_stats qs ON ps.plan_handle = qs.plan_handle
    GROUP BY ps.DatabaseName
        ,ps.ObjectName
        ,ps.usecounts
            ,ps.plan_handle
)
SELECT ps.DatabaseName
    ,ps.ObjectName
      ,ps.usecounts
      ,ps.avg_cpu_time
      ,ps.avg_io
      ,ps.avg_elapsed_time_ms
      ,qp.query_plan
      ,ps.plan_handle
FROM PlansAndStats ps
      CROSS APPLY sys.dm_exec_query_plan(ps.plan_handle) qp 

Executing the script above provides the following output:

image

The output includes the name of the object being sought and a link to the plan from the procedure cache.  Included with this is some basic performance information from sys.dm_exec_query_stats that can be useful in determining performance variations between the plans returned.

Procedure to Find Plans

For those that like to take these scripts and build stored procedures for them.  I’ve also included a script below that includes this information.

Changing A Performance Counter Log Format

We've picked something up on radar!

Ever come across performance counter log that isn’t in your desired format?  This is a situation I’ve been in a number of times.  And wouldn’t you know, I usually space off the command line tool that I can use to do this.

The gem of a tool that you can use to change performance log formats is called relog.  There are a number parameters that can be passed into the tool which are detailed on the TechNet page for relog.

In a simple example, supposed you have a performance counter log named SQLStats.blg that was in a binary format.  And suppose ever further that you needed this log to be in a CSV format.

Executing relog with the following parameters would complete this task above.

relog "SQLStats.blg" -f CSV -o "SQLStats.csv"