Effects of Persisted Columns on Performance

T-SQL
I live for questions. And my favorite questions are the ones where I'm not completely sure of the answer. Those are the questions that make me stop presenting in order to take a note so I can try to answer the question later, usually in a blog post. Guess where we are today? I was asked at SQL Bits in London about the direct impact of the PERSISTED operator on calculated columns, both inserts and selects. I didn't have a specific answer, so I wrote it down for later (and asked the, self-described, persisting Dane, to email me to remind me. He did, so I put together a few tests to try to answer his question. First, I created three tables: CREATE TABLE dbo.PersistTest ( PersistTestID INT IDENTITY(1,1) NOT NULL PRIMARY…
Read More

Does the New Cardinality Estimator Reduce Bad Parameter Sniffing

T-SQL
No. Next question. Although, that answer can be slightly, ever so slightly, nuanced... Parameter sniffing is a good thing. But, like a good wine, parameter sniffing can go bad. It always comes down to your statistics. A very accurate set of statistics with very little data skew (some values that have radically more/less data than other values) and a very even distribution (most values have approximately similar cardinality), and parameter sniffing is your bestest buddy on the planet (next to a tested backup). But, introduce some data skew, let the stats get wildly out of date, or suffer from seriously uneven distribution, and suddenly your best friend is doing unspeakable things to your performance (kind of like multi-statement table valued user defined functions). SQL Server 2014 has the first upgrade…
Read More

Execution Plans, Performance Tuning and Rum

Misc
[caption id="attachment_2827" align="alignleft" width="150"] This is me on the last cruise[/caption] In just a few more weeks I'll be setting sail on the first of two SQL Cruise events this year. I'm honored beyond my ability to appropriately express it to be included as one of the Technical Leads for both the cruise in February (7-14, 2015, I think there's a seat or two left) to the Caribbean and the one in June (14-21, 2015, definitely a couple of seats left) to the Mediterranean. Lest you think that this is just an excuse to hang out and drink, you ought to know a little about how sessions are presented on the cruise and the sessions I'm presenting. Don't mistake sessions on the boat for your typical one hour session at…
Read More

SQL Server Query Performance Tuning

SQL Server, T-SQL
The latest update to my book, SQL Server Query Performance Tuning was released last week. This is the fourth edition of the book, and the third edition that I've been responsible for. At the urging of my editor, Jonathan Gennick, I have completely restructured the book for this release. The chapters have been broken up and rearranged so that they're smaller, more easily consumed. Yes, I've worked with my technical editor, Joe Sack, to add lots of new information and to ensure that the existing information is more accurate and more useful. But, we've also added new chapters on topics that weren't given enough attention in the previous versions of the book, such as parameter sniffing. It can certainly seem like these book releases are just some incremental changes on top of…
Read More

PASS Summit 2014 Pre-Conference Seminar

PASS, T-SQL
I'm putting on a pre-conference seminar (also known as a pre-con) at the PASS Summit this year. I'm really honored to be able to present this and I'm pretty excited about it. So, if you want to talk query tuning, let's get together at the Summit. For a few fun facts about the event, check out this Q&A over at PASS. To register for the event and my pre-con, go here now.
Read More

Left or Right?

SQL Server, T-SQL
No, this is not about politics. It's about your WHERE clause... and your JOIN criteria... and your HAVING clause. It's about a canard that still makes the rounds occasionally. Please, help me put this statement to sleep for once and all: A function on the left side of the equals sign can lead to performance problems Well, you know, it's sort of true. But then, a function on the right side of the equals sign can also lead to performance problems. In short, it's not the placement of the function that causes issues, it's the function that causes issues. Let's take a look at a really simple example: SELECT a.AddressID, a.AddressLine1, AddressLine2 FROM Person.Address AS a WHERE a.AddressLine1 = 'Downshire Way'; This simple query results in an equally simple execution plan: Now,…
Read More

A Full Day of Query Tuning

SQL Server, T-SQL
I'm excited to able to say that I've been given the opportunity to put on a full day workshop at SQL Connections on Friday, September 19th, 2014. The title is "Query Performance Tuning in SQL Server 2014", but I assure you we're going to cover things that are applicable if you're still working on SQL Server 2005. We'll start the day covering the different mechanisms you have to capture query metrics. We'll go over dynamic management objects and extended events that are incredibly important to you in understanding which queries you need to tune. We'll get an introduction into how the optimizer works and the importance that statistics, indexes and constraints play in helping the optimizer make the choices it makes. I promise, execution plans will be covered throughout the…
Read More

Execution Plan Details

PASS, SQL Server, T-SQL
I wouldn't say it's common knowledge that you should look at execution plans when tuning queries, but it's not exactly uncommon knowledge either. But, people tend to get focused on just looking at the graphical part of the plan and there's just not enough information there. Let's take a look at a query: SELECT pc.Name, ps.Name, v.Name, pr.ReviewerName, p.Name, v.ModifiedDate, p.Color FROM Production.Product AS p LEFT JOIN Production.ProductReview AS pr ON pr.ProductID = p.ProductID JOIN Production.ProductSubcategory AS ps ON p.ProductSubcategoryID = ps.ProductSubcategoryID JOIN Production.ProductCategory AS pc ON pc.ProductCategoryID = ps.ProductCategoryID JOIN Purchasing.ProductVendor AS pv JOIN Purchasing.Vendor AS v ON v.BusinessEntityID = pv.BusinessEntityID ON pv.ProductID = p.ProductID WHERE v.ModifiedDate = '2006-02-17 00:00:00.000' AND p.Color LIKE 'Y%'; This generates an execution plan that looks like this: Neither v.ModifiedDate nor p.Color have indexes.…
Read More

Statistics and Natively Compiled Procedures

T-SQL
Statistics are one of the single most important driving factors for the behavior of the query optimizer. The cardinality estimates stored within the statistics drive costing and costing drives the decision making of the optimizer. So, how does this work with the new SQL Server 2014 natively compiled procedures? Differently. In-memory tables do not maintain their statistics automatically. Further, you can't run DBCC SHOW_STATISTICS to get information about those statistics, so you can't tell if they're out of date or not or what the distribution of the data is within them. So, if I create some memory optimized tables, skip loading any data into them and then run this standard query: SELECT a.AddressLine1, a.City, a.PostalCode, sp.Name AS StateProvinceName, cr.Name AS CountryName FROM dbo.Address AS a JOIN dbo.StateProvince AS sp ON sp.StateProvinceID =…
Read More

The Utility of Execution Plans in Natively Compiled Procedures

T-SQL
I'm actually having problems identifying the utility of execution plans when working with natively compiled procedures. Or, put another way, why bother? I've posted a couple of times on natively compiled procedures and SQL Server execution plans. I've found the differences interesting and enlightening, but I'm seriously questioning why I should bother, at least currently. I'm sure there will be many changes to the behaviors of the natively compiled procedures and their relationship with execution plans. But right now, well, let's look at an example. I have three simple tables stored in-memory. Here's the definition of one: CREATE TABLE dbo.Address ( AddressID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY NONCLUSTERED HASH WITH (BUCKET_COUNT = 50000), AddressLine1 NVARCHAR(60) NOT NULL, AddressLine2 NVARCHAR(60) NULL, City NVARCHAR(30) COLLATE Latin1_General_100_BIN2 NOT NULL, StateProvinceID INT…
Read More