Tag performance tuning

Links for the Week 2009-03-27

SQL Server

Database Manager for IIS 7 RC Preview IIS 7 has a lot of great features built-in, not the least of which is its ability to host mini-apps. Ever use PHPMySQLAdmin? Ever wish you had a tool like that for SQL Server? Now you do. Developers rejoice, you no longer need to install SSMS after Visual Studio installs a copy of SQL Server that you can only access programmatically.

Database Maintenance Best Practices Part II – Setting FILLFACTOR Ever want to know more about FILLFACTOR than you ever thought you wanted to know? Kim Tripp takes a look into an oft overlooked aspect of index and database design/tuning. I now know more about FILLFACTOR than I thought there was to know.

Dev, Test and Production SQL Server environments Ever wonder what smart people think about how to dest up a dev, test, and production SQL Server environment? Brent Ozar goes over his ideas and best practices for a SQL Server environment based on years of tried and true experience.

Development

Mega drop-down navigation at Basecamp and Rails Guides site While this isn’t exactly development related, it’s web development, which is close enough in my book. UI styling is very important – it influences how the users interact with your application and, most importantly, how they perceive and interact with the underlying data. Make this action easier and painless and the users will be much happier (trust me).

Visual Studio Addins – SmartPaster and CopySourceAsHTML Ever want to paste in text as code documentation? How about as a #region in your C#? Ever want to export that method as highlighted HTML? Well, now you can do that easily!

Stuff & Things

Logon Changer Customizes the Windows 7 Login Screen Want to pretty up your Windows 7 machine with a custom login screen? DO IT!

Extreme Sheep LED Art Special thanks to William Gibson for bringin

Production Problems, Community, and You

How many of you out there have had production issues? You, the liar in the back, put your hand up. Well, we experienced a major performance issue in production last week.

For those that don’t know, I’m not a production DBA. I’m what they call a “development DBA.” I write stored procedures, tune the SQL, write indexes, and work with developers to ensure speedy data access. As someone who comes from the software development world, it’s a logical place to be. But, history aside, I don’t possess the knowledge of the SQL Server internals like many of my production DBA brethren.

Back to the problem at hand. On Wednesday, the users started noticing exceptional slow downs in the application. These weren’t the usual slow downs where things took a little bit longer than expected, queries that normally took 2 seconds were taking minutes to come back. Since our ASP.NET application is, largely, a passthrough that calls stored procedures and loads the results into a datagrid, we quickly ruled out application performance. Plus, I tested some stored procedures on the production database and they ran slowly. (I say our application is largely a passthrough, but I don’t mean to do a disservice to the developers. It is quite a sophisticated piece of software, it just doesn’t do a lot of heavy lifting.)

Luckily, I was able to leverage a few resources to resolve this issue.

1) Blogs

I subscribe to a lot of blogs. A LOT of blogs. From reading Brent Ozar’s blog, I remembered that he has a section at the top of his website on using perfmon and another on performance tuning. It also helps that he recently presented at the CBusPASS user group on using perfmon. I fired up my browser, went to Brent’s blogs, and started working with the monitoring set up that he outlined. This got me going pretty quickly and gave me a great deal of information.

In addition to checking up on Brent’s step by step instructions, I remembered that another SQL Server blogger had posted a SQL script to find the top 10 slowest running queries and their execution plans. I couldn’t (and still can’t) remember who wrote it. Which leads to:

2) Social Networks

In this case, Twitter. I opened up TweetDeck and sent out a tweet with a question asking if anyone had seen that blog post. Someone remembered what I was talking about and sent me a link. Since I’m not much of a production DBA, yet, I kept raising questions on twitter which were rapidly answered by many different people. I was able to work with them to figure out the best solution to my specific questions and move forward quickly.

Within 15 minutes, I was armed with a methodology to track down root cause of the problem as well as a query that would help me pinpoint any specific query problems. Without the collective knowledge of the SQL Server DBA community, it would have taken me a lot longer to understand and solve the problem.

It turns out that the problem was a missing column in an index that caused a full table scan on one of the largest tables in the database which, in turn, caused locking issues.

CBusPASS Meeting 2009.02.12

We had our second user group meeting tonight, and I would like to send a special thanks to Brent Ozar for being willing to present. We had around twenty people in attendance physically and another dozen or so in attendance virtually via Live Meeting.

The resources from Brent’s presentation on Perfmon and Profiler are available online at the CBusPASS Meeting Archive.

Brent’s posts about Perfmon and analytics are available online:
http://www.BrentOzar.com/perfmon
http://www.BrentOzar.com/perfmoncloud

In addition, Brent mentioned Excel Table Analysis Tools for the Cloud:
http://www.SQLServerDataMining.com/cloud

In addition, Brent is the Editor-in-Chief for SQL Server Pedia (where this blog is also syndicated).

Thanks again, Brent, for taking your time to present. I’d also be an awful user group leader if I didn’t thank my steering committee for their invaluable help, Battelle For Kids for providing the meeting space, and Quest Software for providing the Live Meeting.

For those who missed out, Brent will be giving this presentation again on February 19 with the West Michigan SQL Server User Group. You can find more info on Brent’s upcoming events page.

How I Get By Without sysadmin

The people who follow me on twitter have probably noticed that when I’m not tweeting absolute nonsense, I’m tweeting about performance tuning SQL. What most people don’t know is that I don’t have sysadmin access on our servers, nor do I have any of the other permissions that would let me collect trace information or access the dynamic management views. I’ll be honest, at first I thought this would be an insurmountable task – how could I possibly tune queries without access to the tools that I have typically used to tune queries? Eventually, I realized that I always had the knowledge that the tools provided, so I got to work putting this knowledge to work for me.

Write Queries Organically

What the hell? Queries aren’t fruit salad! You’re absolutely right, but it’s still possible to do a bit of genetic programming when working on a query. Here’s how this process works for me:

  1. A query request comes in with a query attached from the previous system.
  2. I take a look at the old report and read the SQL so I can understand what’s going on.
  3. I slowly build the core query in SSMS before I create any dynamic logic.
  4. I add of the dynamic logic, test it a few times, and then throw it over the wall for the development team to play with.

Building the core query is where genetic programming comes into play. As I write a query, I’ll start with a core table and slowly add in additional tables and predicates one at a time until I’ve built my query. The whole time I’m doing this, I keep telling SSMS to return the actual execution plan. Normally, if everything runs quickly, I give the execution plan a quick once over with each step to look for glaring trouble spots that need attention before I move on. As I move through the query, I don’t add any aggregation, I just keep adding tables, predicates, and output columns. This lets see where I need to group, verify the data I’m getting, and actually see the raw data before I start aggregating values. This last part is extremely helpful when you’re dealing with CTEs and aggregates.

How does this help me tune the query? Whenever there is a slow down because of a bad join or missing index it’s immediately visible and I can take action. Remember how I said I always return the actual execution plan? There’s a reason for that. I can open up the execution plan and quickly determine what is causing the slow down. If a query goes from taking about a second to 30 seconds, I know that I’ve either done something incredibly wrong or else I’ve missed something in a join or where clause.

Start Small

Whenever I start writing a query, I start with the table and conditions that will filter down results the fastest. This comes from knowing how SQL Server builds query results – I suggest taking a look at Itzik Ben-Gan’s fantastic book Inside Microsoft SQL Server 2005: T-SQL Querying for an introduction to this topic. Basically, I find the conditions that will be the most restrictive and build my query out from there. I work with a range of data that covers 7 years and the detail tables contain 40,000,000+ rows. This isn’t a lot in the grand scheme of things, but when seconds matter, it’s important to have the smallest possible number of records to join on before you get to the monster table.

Cheat and Use Hints

When all else fails, or when the execution plan is just plain bad, I look at the indexes being used and I compare them to the possible indexes on the table. There are covering indexes in place for most common queries on any single table. When it makes sense, I force the engine to use specific indexes through judicious application of index hints. What I don’t do is feed my queries into the Database Tuning Advisor and apply the indexes it suggests. I do use the DTA tools to look for indexes that I might have missed, but I create indexes myself and occasionally, carefully, combine its suggestions with my own to create better covering indexes.

When working almost exclusively with dynamic SQL, it’s important to provide index hints since the number of possible execution plans is staggering and SQL Server will not be able to hold them all in memory. It’s better (and cheaper) to front load the brainpower during query development than to find out that you have poorly performing queries and have to rewrite them on the fly while customers are calling up and complaining about poor performance.

Avoid Parameter Sniffing

Parameter sniffing is when SQL Server caches the values of variables passed into the query for later re-use. The problem is that these might be infrequently used values or the values might always be different. When you have multiple clients accessing the database and @ClientId is a parameter for every query, you don’t want that value to be cached. Instead, I immediately copy stored procedure parameters to a second set of internal parameters. Unfortunately, I lose the advantage of caching if there are common queries that will always use the same or similar parameters, so I’m careful about how I do this. When it makes sense, I don’t copy parameter values.

Careful Conditions

One of the easiest places to lose performance is by writing poorly performing where clauses. Essentially, make sure the columns in your where conditions are always using an indexed column and that you are using the columns in a way that will make use of the index – WHERE DATEPART(yyyy, my_col) > 2006 isn’t going to cut it. Denis Gobo has a great write up on this topic over at Less Than Dot.

Conclusion

There are a lot of great tools out there, both within SQL Server and from third party vendors, that make this process easier. It’s also important to realize that these are skills that we all have and can put to use before resorting to tools to get the last 10 or 20% of performance tuning.

Related Topics

Here are two related articles about security within SQL Server.

SQL Server Security – Database Roles
Flexible Database-Level Roles

This site is protected with Urban Giraffe's plugin 'HTML Purified' and Edward Z. Yang's Powered by HTML Purifier. 401 items have been purified.