Posts belonging to Category SQL Server 2008 R2



Webcast Today – Using XML to Query Execution Plans

I’ll be speaking for the SQL PASS Database Administration Virtual Chapter today at 12 PM Eastern time.  The topic will be Using XML to Query Execution Plans.  The abstract for the event is the following:

SQL Server stores its execution plans as XML in dynamic management views. The execution plans are a gold mine of information. From the whether or not the execution plan will rely on parallelism to what columns are requiring a key lookup after a non-clustered index seek. Through a the use of XML this information can be available at your fingertips to help determine the value and impact of an index and guide you in improving the performance of your SQL Server databases. In this session we’ll look at how you can begin to understand and query the structure of the execution plans in the procedure cache. Also, we’ll review how to uncover some potential performance issues that may be lurking in your SQL Server.

You can get to the event here.

Webcast Next Week – Using XML to Query Execution Plans

I’ll be speaking for the SQL PASS Database Administration Virtual Chapter next week.  It’ll be on July 28 at 12 PM Eastern time.  The topic will be Using XML to Query Execution Plans.  The abstract for the event is the following:

SQL Server stores its execution plans as XML in dynamic management views. The execution plans are a gold mine of information. From the whether or not the execution plan will rely on parallelism to what columns are requiring a key lookup after a non-clustered index seek. Through a the use of XML this information can be available at your fingertips to help determine the value and impact of an index and guide you in improving the performance of your SQL Server databases. In this session we’ll look at how you can begin to understand and query the structure of the execution plans in the procedure cache. Also, we’ll review how to uncover some potential performance issues that may be lurking in your SQL Server.

If you register for the event ahead of time you will be entered into a drawing brought to us from CA, our event sponsor.  You can get to the event here.

Webcast Today – Performance Impacts Related to Different Function Types

I’ll be speaking for the SQL PASS Performance Virtual Chapter later today starting at 12 PM Eastern time.  The topic will be Performance Impacts Related to Different Function Types.  The abstract for the event is the following:

User defined functions provide a means to encapsulate business logic in the database tier.  Often the purpose of the encapsulation is to provide standard method access segments of data within the database.  Unfortunately, not all methods of creating user defined functions are equal.  In this session we’ll review the types of user defined functions and investigate the performance impact in selecting the different types

Goals:

  • Identify purposes for creating user defined functions
  • Discuss the types of user-defined functions
  • Demonstrate performance impact in selecting different types of functions

You can get to the event here.

Displaying Microsoft Project Task’s Notes in SSRS 2008

Lego Deadlock

I was asked to take a look at an issue the other day regarding displaying Microsoft Project Task’s Notes in SSRS 2008.  If you’ve worked with building reports for Microsoft Project Server, you have no doubt dealt with the RTF data that is stored in the Task’s Notes fields.

With SQL Server 2005 Reporting Services (SSRS) it was easy to display this information by following the steps outlined in Christophe Fiessinger post “How to display Microsoft Project Task’s Notes field in a report”.

But What About SSRS 2008

With SSRS 2008, the Reporting Services engine was re-architected.  Some of this new architecture included an improvement in the underlying security.  The question is did these changes have an effect the method available in the blog previously linked.

Unfortunately, it does.  Instead of displaying notes from Project Server as desired, you end up with row after row of N/A – as seen below.

image As a result, the code used for SSRS 2005 to display the RTF will not work with SSRS 2008.  Digging into the error message reveals that the reason that all of the tasks display as N/A is the following error message:

System.Security.SecurityException: Request for the permission of type ‘System.Security.Permissions.UIPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089′ failed.
at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
at System.Security.CodeAccessPermission.Demand()
at System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
at System.Windows.Forms.Control.CreateHandle()
at System.Windows.Forms.Control.get_Handle()
at System.Windows.Forms.Application.ParkHandle(CreateParams cp)
at System.Windows.Forms.Control.CreateHandle()
at System.Windows.Forms.TextBoxBase.CreateHandle()
at System.Windows.Forms.RichTextBox.set_Rtf(String value)
at ReportExprHostImpl.CustomCodeProxy.byteArrayToString(Byte[] b)
The action that failed was:
Demand
The type of the first permission that failed was:
System.Security.Permissions.UIPermission
The Zone of the assembly that failed was:
MyComputer

No good.  The solution fails to function anymore because of the attempt to implement System.Windows.Forms.RichTextBox from within SSRS.  The new security restriction prevent this.

Can It Be Implemented Differently?

Investigating this more, I found an post on the Microsoft forums that dealt with issue.  In that post, there was a reference to a StackOverflow question that also was looking for a solution to this issue.

Both posts point towards adding the following function to the report:

Public Function ConvertRtfToTextRegex(ByVal input As String) As String
        Dim returnValue As String = String.Empty
        returnValue = System.Text.RegularExpressions.Regex.Replace(input, "\{\*?\\[^{}]+}|[{}]|\\\n?[A-Za-z]+\n?(?:-?\d+)?[ ]?", "")
        Return returnValue
End Function

Instead of the code from the original Project Server post the code for the SSRS report should look like this:


'Instantiate a stringbuilder object
Public s As New System.Text.StringBuilder() 

Public Function byteArrayToString(ByVal b() As Byte) As String
    Dim i As Integer
    dim mystr as string 

Try
    s.length = 0 

    For i = 0 To b.Length - 1
        If i <> b.Length - 1 Then
            s.Append(chr(b(i)))
        End If
    Next 

    mystr = left(s.ToString, len(s.ToString)-1) 

    return ConvertRtfToTextRegex(mystr)
Catch ex as exception
    return ex.tostring()
    s.length = 0 

End Try
End Function 

Public Function ConvertRtfToTextRegex(ByVal input As String) As String
        Dim returnValue As String = String.Empty
        returnValue = System.Text.RegularExpressions.Regex.Replace(input, "\{\*?\\[^{}]+}|[{}]|\\\n?[A-Za-z]+\n?(?:-?\d+)?[ ]?", "")
        Return returnValue
End Function

After adding the new code, the values that come back start looking as they would have with SSRS 2005.  Problem solved!

image

Follow-Up

While I’ve provided a solution to this issue, there is a little more to be garnered from this solution.  That is the power of the SQL Server community.  In solving this I didn’t have to have any inherent knowledge of UIPermissions and how they got hosed up because SSRS 2008 is more secure.  This is a good thing by the way. I also didn’t have to know how to write a goofy regular expression.  Thank God!

All I had to do was to take what I knew and start to search for items that were similar and follow where the trail led me.  In this way the common knowledge of the community was shared previously and I am sharing it again myself.

It’s a good thing to share what you know.  Whether through answering questions on forums, writing blog posts, or participating in your local SQL Server user groups.  This helps raise the bar for everyone else and expands the knowledge of our community.

SQL Server Best Practice Whitepapers

OMG

If you talk to Sarah (twitter), she’ll tell you that I like lists.  Lists are awesome – they are almost like non-structured data.  They are hierarchies of information that I can work with.  They are Data.

Microsoft must have known I liked lists because over the weekend I discovered (see below) their SQL Server Best Practice Whitepapers list.

If you are looking to shore up your environment and skills, this is the place to start.  Check it out – you’ll find some great stuff here.

UPDATE:

By discover above… I should have mentioned that I saw it on a post by Mark Broadbent (blog | twitter).  Attribution is always a good thing and I feel bad that I missed that one.

Webcast Next Week – Performance Impacts Related to Different Function Types

I’ll be speaking for the SQL PASS Performance Virtual Chapter next week.  It’ll be on July 6 at 12 PM Eastern time.  The topic will be Performance Impacts Related to Different Function Types.  The abstract for the event is the following:

User defined functions provide a means to encapsulate business logic in the database tier.  Often the purpose of the encapsulation is to provide standard method access segments of data within the database.  Unfortunately, not all methods of creating user defined functions are equal.  In this session we’ll review the types of user defined functions and investigate the performance impact in selecting the different types

Goals:

  • Identify purposes for creating user defined functions
  • Discuss the types of user-defined functions
  • Demonstrate performance impact in selecting different types of functions

You can get to the event here.

Do You Patch SQL Server Regularily?

Lego DeadlockMicrosoft has released a few new Cumulaive Update for SQL Server. There is an update for each of the supported releases of SQL Server:

Cumulative Updates are primarily intended for SQL Server environments where the issues being resovled are being realized. Though if you are using the components updated by the Cumulative Update it would be good to apply the update.

Unless, of course, you’d rather spend the weekend behind an 8-Ball troubleshooting and resolving an issue that the Cumulative Update would have prevented. The 8-Ball might be a black and blue ball by Monday when you explain to your manager that the issue was completely avoidable.

Patch Regularily

If you aren’t aware, Microsoft has an Incremental Servicing Model. This model provides guidance on what you should expect from Microsoft from a support standpoint for issues with their products. As part of the Incremental Servicing Model, Microsoft is committed to releasing Cumulative Updates every 2 months.

All fine and dandy but what does that have to do with you? Or if today still feels like Monday… So what?

The benefit of this model is that it allows us as administrators of SQL Server to develop a plan to regularily download and install the updates. This plan would, of course, include a process to install the updates in the development and test environments. And, also, detail what the steps are for testing and releasing these updates.

But That’s Not All

Just like practicing your database recovery plan. You do practice this, right? Regularily updating your SQL Server environment provides an opportunity to become familiar with this task. This is a critical skill that every DBA should want to have.

If you are well versed in a simple Cumulative Update deployment you have skill and knowledge that will be critical in other situations. When a hotfix needs to be deployed, you will already know your systems well enough to understand the collateral impact of the deployment. If you suddenly inherit a SQL Serve that hasn’t been maintained since an RTM install, you know what level of patching to place on the server and already have a process in place to get the job done.

Regular updates of your SQL Server environment also gives you the opportunity to read the Cumulative Update notes. You will know what wasn’t working and become an expert on problems that may exist in your environment. I’d rather say, “There is a fix to that issue already in progress. It’s in the Test environment already.” Than have to come back and say, “Microsoft fixed that in an update 6 months ago, I’ll see what we need to do to get the update deployed.”

There are likey countless other reasons to take the time to build a process and skillset around regular patching. The long and the short of it is that it is good for you, good for your company, and the responsible thing to do.

Index Those Foreign Keys

Lego DeadlockToday started with some quality time getting to know a deadlock that had occurred. While working through the deadlock, I noticed that there were a number of foreign key relationships that weren’t indexed on the parent side of the relationship.

I am going to skip over the why to index foreign keys and save that for a later point when I have more time to go through it with some really pretty pictures. Today though, I want to share the scripts that I put together to look for these situations and help prevent issues related to them.

Brute Force Indexing

This first script is a brute force attack on this need. If you set the output for text results in SQL Server Management Studio (SSMS) you’ll get a script with all of the indexes you’ll need to cover all of your foreign key relationships.


SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SET NOCOUNT ON

;WITH cIndexes
AS (
SELECT i.object_id
,i.name
,(SELECT QUOTENAME(ic.column_id,'(')
FROM sys.index_columns ic
WHERE i.object_id = ic.object_id
AND i.index_id = ic.index_id
AND is_included_column = 0
ORDER BY key_ordinal ASC
FOR XML PATH('')) AS indexed_compare
FROM sys.indexes i
), cForeignKeys
AS (
SELECT fk.name AS foreign_key_name
,'PARENT' as foreign_key_type
,fkc.parent_object_id AS object_id
,STUFF((SELECT ', ' + QUOTENAME(c.name)
FROM sys.foreign_key_columns ifkc
INNER JOIN sys.columns c ON ifkc.parent_object_id = c.object_id AND ifkc.parent_column_id = c.column_id
WHERE fk.object_id = ifkc.constraint_object_id
ORDER BY ifkc.constraint_column_id
FOR XML PATH('')), 1, 2, '') AS fk_columns
,(SELECT QUOTENAME(ifkc.parent_column_id,'(')
FROM sys.foreign_key_columns ifkc
WHERE fk.object_id = ifkc.constraint_object_id
ORDER BY ifkc.constraint_column_id
FOR XML PATH('')) AS fk_columns_compare
FROM sys.foreign_keys fk
INNER JOIN sys.foreign_key_columns fkc ON fk.object_id = fkc.constraint_object_id
WHERE fkc.constraint_column_id = 1
UNION ALL
SELECT fk.name AS foreign_key_name
,'REFERENCED' as foreign_key_type
,fkc.referenced_object_id AS object_id
,STUFF((SELECT ', ' + QUOTENAME(c.name)
FROM sys.foreign_key_columns ifkc
INNER JOIN sys.columns c ON ifkc.referenced_object_id = c.object_id AND ifkc.referenced_column_id = c.column_id
WHERE fk.object_id = ifkc.constraint_object_id
ORDER BY ifkc.constraint_column_id
FOR XML PATH('')), 1, 2, '') AS fk_columns
,(SELECT QUOTENAME(ifkc.referenced_column_id,'(')
FROM sys.foreign_key_columns ifkc
WHERE fk.object_id = ifkc.constraint_object_id
ORDER BY ifkc.constraint_column_id
FOR XML PATH('')) AS fk_columns_compare
FROM sys.foreign_keys fk
INNER JOIN sys.foreign_key_columns fkc ON fk.object_id = fkc.constraint_object_id
WHERE fkc.constraint_column_id = 1
), cRowCount
AS (
SELECT object_id
,SUM(row_count) AS row_count
FROM sys.dm_db_partition_stats ps
WHERE index_id IN (1,0)
GROUP BY object_id
)
SELECT
'--Missing foreign key index for '+fk.foreign_key_name+CHAR(13)+CHAR(10)+'GO'+CHAR(13)+CHAR(10)+
+'CREATE NONCLUSTERED INDEX FKIX_'+OBJECT_NAME(fk.object_id)+'_'+REPLACE(REPLACE(REPLACE(REPLACE(fk.fk_columns,',',''),'[',''),']',''),' ','')
+CHAR(13)+CHAR(10)+
+'ON [dbo].['+OBJECT_NAME(fk.object_id)+'] ('+fk.fk_columns+')'+CHAR(13)+CHAR(10)+
+'GO'+CHAR(13)+CHAR(10)+CHAR(13)+CHAR(10)
FROM cForeignKeys fk
INNER JOIN cRowCount rc ON fk.object_id = rc.object_id
LEFT OUTER JOIN cIndexes i ON fk.object_id = i.object_id AND i.indexed_compare LIKE fk.fk_columns_compare + '%'
WHERE i.name IS NULL
ORDER BY OBJECT_NAME(fk.object_id), fk.fk_columns

Foreign Key Monitoring

This second script accommodates for those situations when you may not want to just index every foreign key that is out there. Maybe there’s a really old table in the database with a foreign key relationship that just doesn’t matter any more. Is it worth indexing along a vector that won’t lead to any performance impact – either negative or positive? Most likely not.

For this script, the results output a list of foreign keys relationships that are not fully indexed. Included in the result script is a column with XML data in it that contains a script for creating an index. You may notice that the format for this is very similar to the schema created when outputtingmmissing Indexes from execution plans.


SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

;WITH cIndexes
AS (
SELECT i.object_id
,i.name
,(SELECT QUOTENAME(ic.column_id,'(')
FROM sys.index_columns ic
WHERE i.object_id = ic.object_id
AND i.index_id = ic.index_id
AND is_included_column = 0
ORDER BY key_ordinal ASC
FOR XML PATH('')) AS indexed_compare
FROM sys.indexes i
), cForeignKeys
AS (
SELECT fk.name AS foreign_key_name
,'PARENT' as foreign_key_type
,fkc.parent_object_id AS object_id
,STUFF((SELECT ', ' + QUOTENAME(c.name)
FROM sys.foreign_key_columns ifkc
INNER JOIN sys.columns c ON ifkc.parent_object_id = c.object_id AND ifkc.parent_column_id = c.column_id
WHERE fk.object_id = ifkc.constraint_object_id
ORDER BY ifkc.constraint_column_id
FOR XML PATH('')), 1, 2, '') AS fk_columns
,(SELECT QUOTENAME(ifkc.parent_column_id,'(')
FROM sys.foreign_key_columns ifkc
WHERE fk.object_id = ifkc.constraint_object_id
ORDER BY ifkc.constraint_column_id
FOR XML PATH('')) AS fk_columns_compare
FROM sys.foreign_keys fk
INNER JOIN sys.foreign_key_columns fkc ON fk.object_id = fkc.constraint_object_id
WHERE fkc.constraint_column_id = 1
UNION ALL
SELECT fk.name AS foreign_key_name
,'REFERENCED' as foreign_key_type
,fkc.referenced_object_id AS object_id
,STUFF((SELECT ', ' + QUOTENAME(c.name)
FROM sys.foreign_key_columns ifkc
INNER JOIN sys.columns c ON ifkc.referenced_object_id = c.object_id AND ifkc.referenced_column_id = c.column_id
WHERE fk.object_id = ifkc.constraint_object_id
ORDER BY ifkc.constraint_column_id
FOR XML PATH('')), 1, 2, '') AS fk_columns
,(SELECT QUOTENAME(ifkc.referenced_column_id,'(')
FROM sys.foreign_key_columns ifkc
WHERE fk.object_id = ifkc.constraint_object_id
ORDER BY ifkc.constraint_column_id
FOR XML PATH('')) AS fk_columns_compare
FROM sys.foreign_keys fk
INNER JOIN sys.foreign_key_columns fkc ON fk.object_id = fkc.constraint_object_id
WHERE fkc.constraint_column_id = 1
), cRowCount
AS (
SELECT object_id
,SUM(row_count) AS row_count
FROM sys.dm_db_partition_stats ps
WHERE index_id IN (1,0)
GROUP BY object_id
)
SELECT
fk.foreign_key_name
,OBJECT_NAME(fk.object_id) AS fk_table_name
,fk.fk_columns
,rc.row_count AS row_count
,CAST('<!--dex  '+CHAR(13)+CHAR(10)+'Missing foreign key index for '+fk.foreign_key_name+CHAR(13)+CHAR(10)+CHAR(13)+CHAR(10)+'USE ['+DB_NAME()+']'<br--> +CHAR(13)+CHAR(10)+'GO'+CHAR(13)+CHAR(10)+
+'CREATE NONCLUSTERED INDEX []'+CHAR(13)+CHAR(10)+
+'ON [dbo].['+OBJECT_NAME(fk.object_id)+'] ('+fk.fk_columns+')'+CHAR(13)+CHAR(10)+
+'GO'+CHAR(13)+CHAR(10)+'--?>' AS xml) foreign_key_index_schema
FROM cForeignKeys fk
INNER JOIN cRowCount rc ON fk.object_id = rc.object_id
LEFT OUTER JOIN cIndexes i ON fk.object_id = i.object_id AND i.indexed_compare LIKE fk.fk_columns_compare + '%'
WHERE i.name IS NULL
ORDER BY OBJECT_NAME(fk.object_id), fk.fk_columns

Closing Up

The DDL schema output in these scripts is very basic. It doesn’t account for potentially important things like partitions and filegroups. Obviously, you’ll need to modify this for your own environment and don’t just run this on production.

I see a lot of potential in these scripts and am planning to include them as part of preparing for releases when I am clients. A good way to dot the i’s and cross the t’s.

Individual results may vary. No Legos were harmed in the writing on this post.

You Thought You Missed 24 Hours of PASS

Go get the popcorn and let’s get ready to watch some PASS sessions!  Last month PASS hosted an event called 24 Hours of PASS.  In this event, there were 24 back to back webcasts that focused on SQL Server and more specifically SQL Server 2008 R2.  As if that weren’t awesome enough, you can now go back and watch any of the 24 Hours of PASS sessions that you may have missed.

So if you weren’t downing the Red Bull and missed some or all of the sessions, you don’t need to feel left out any longer.  Here’s a list of the available topics:

  • Introduction to PowerPivot (Brian Knight)
  • Database Development Patterns (Andy Leonard)
  • What Exactly is in SQL Server 2008 R2 (Kevin Cox)
  • Getting Started with SQL Server Utility in SQL Server 2008 R2 (Glenn Berry)
  • Data Tier Applications (Jacob Sebastien)
  • What’s Really Happening on Your Server? 15 Powerful SQL Server Dynamic Management Objects (Adam Machanic)
  • Filtered Indexes, Sparse Columns: Together, Separately (Don Vilen)
  • Solving Common Business Problems with Microsoft PowerPivot (Donald Farmer)
  • Exploring SQL Server 2005 and 2008 Security (Don Kiely)
  • Using Data Compression with SQL Server 2008 and 2008 R2 (Maciej Pilecki)
  • Easier than Ever Report Authoring in SSRS 2008 R2 (Jessica M. Moss)
  • High Performance Functions (Simon Sabin)
  • Manage Your DBA Career, Don’t Let it Manage You (Brad McGehee)
  • Top 10 Mistakes on SQL Server (Kevin Kline)
  • Producing Dashboards with PerformancePoint Services (Peter Myers)
  • Reporting Services Enhancements in SQL Server 2008 (Greg Low)
  • SQL Tuning – Get it Right the First Time (Dean Richards)
  • Managing SSIS Package Deployments with Powershell (Sean McCown)
  • Multi-Server Management With UCP, MDW and PBM (Chuck Heinzelman)
  • Advanced T-SQL Query Tuning Techniques (Rob Farley)
  • Implementing MDM Using SQL Server 2008 R2 Master Data Services (Rushabh Mehta)
  • SQL 2008 R2 How to Manage CPU’s, Cores and CPU Groups (Thomas Grohser)
  • Database Design Fundamentals (Louis Davidson)
  • BLITZ! 60 Minute Server Takeovers (Brent Ozar)

You’ll need to be a PASS member to view the sessions, but if you are interested in them you shouldn’t have an issue with that.

PASSMN June Meeting Today

Minnesota SQL Server Users Group

Don’t forget, PASSMN June Meeting is today.  We have Lara Rubbelke (twitter | blog) coming in to talk about some of the new SSRS features in SQL Server 2008 R2.

More details can be found here.