Launch week: the Season Pass & Fundamentals Week are 50% off — ends in 7d 21h 57mSee the sale

Category: How to Think Like the SQL Server Engine

[Video] How to Think Like the SQL Server Engine: All-Demo Edition

You’ve heard of my free How to Think Like the Engine class, and maybe you even started watching it, but…it has slides, and you hate slides.

Wanna see me do the whole thing in Management Studio, starting with an empty query window and writing the whole thing out from scratch live? This session is for you.

Read more about [Video] How to Think Like the SQL Server Engine: All-Demo Edition 3 comments — Join the discussion
Performance Tuning

How to Think Like the Engine: When a Seek Isn’t

In our last episode, I introduced the concept of scan predicates: execution plan operations that weren't able to seek directly to the rows they needed. Let's take another query:
[crayon-6a4717e18c473446128847/]
If we ONLY have the gray pages index on LastAccessDate, Id, DisplayName, and Age, our query plan looks like this:

I'm going to narrate this from bottom up because it makes for easier storytelling:

Read more about How to Think Like the Engine: When a Seek Isn’t 5 comments — Join the discussion
Performance Tuning

How to Think Like the Engine: Index Column Order Matters a LOT.

We've been working with the clustered index of the Users table, which is on the Identity column - starts at 1 and goes up to a bajillion:

And in a recent episode, we added a wider nonclustered index on LastAccessDate, Id, DisplayName, and Age:
[crayon-6a4717e195c2a146467468/]
Whose leaf pages look like this:

Read more about How to Think Like the Engine: Index Column Order Matters a LOT. 2 comments — Join the discussion
Performance Tuning

How to Think Like the SQL Server Engine: Included Columns Aren’t Free.

In our last cliffhanger episode, I said that if we ran this query: [crayon-6a4717e195e15889477831/] And we had this index: [crayon-6a4717e195e1b569103938/] Then we would have to do all of these things: Look up user #643 on the clustered index by doing a seek - because thankfully our kind developer included the clustered primary key in the…

Read more about How to Think Like the SQL Server Engine: Included Columns Aren’t Free. 3 comments — Join the discussion
Performance Tuning

How to Think Like the SQL Server Engine: Should Columns Go In the Key or the Includes?

In our last episode, in between crab rangoons, I had you create either one of these two indexes:
[crayon-6a4717e196031971574403/]
And I said that the leaf pages of either index would look the same:

In terms of the space they take up on the leaf pages, it doesn't matter whether columns are in the keys of an index or in the includes. It's the same amount of space on the leaf pages. To see it, run sp_BlitzIndex focused on that table:

Read more about How to Think Like the SQL Server Engine: Should Columns Go In the Key or the Includes? 27 comments — Join the discussion
Performance Tuning

How to Think Like the SQL Server Engine: Building Wider Indexes to Deal with Bad T-SQL

In our last episode, we were running into problems with these two queries: [crayon-6a4717e196568167056640/] When SQL Server saw the function in the second query's WHERE clause, it punted out with a 1-row estimate, which caused us problems. SQL Server did an index seek + key lookup where it wasn't appropriate. Well, if we're not allowed…

Read more about How to Think Like the SQL Server Engine: Building Wider Indexes to Deal with Bad T-SQL 3 comments — Join the discussion

How to Think Like the SQL Server Engine: When Statistics Don’t Help

In our last episode, we saw how SQL Server estimates row count using statistics. Let's write two slightly different versions of our query - this time, only looking for a single day's worth of users - and see how its estimations go: [crayon-6a4717e19674a050001154/] Both of those queries are theoretically identical in that they accomplish the…

Read more about How to Think Like the SQL Server Engine: When Statistics Don’t Help 16 comments — Join the discussion

How to Think Like the SQL Server Engine: Using Statistics to Build Query Plans

In our last episode, SQL Server was picking between index seeks and table scans, dancing along the tipping point to figure out which one would be more efficient for a query.

One of my favorite things about SQL Server is the sheer number of things it has to consider when building a query plan. It has to think about:

Read more about How to Think Like the SQL Server Engine: Using Statistics to Build Query Plans 8 comments — Join the discussion
Performance Tuning

How to Think Like the SQL Server Engine: What’s the Tipping Point?

In our last episode, I'd expanded our query to include DisplayName and Age - two columns that weren't in our nonclustered index: [crayon-6a4717e196d0b411340605/] So as a result, I was getting key lookups in the execution plan: And I spent a lot of time talking about the overhead that each key lookup incurs. Astute readers among…

Read more about How to Think Like the SQL Server Engine: What’s the Tipping Point? 5 comments — Join the discussion
Performance Tuning

How to Think Like the SQL Server Engine: What’s a Key Lookup?

In our last couple of queries, we've been using a simple query to find the Ids of everyone who accessed the system since mid-2014:
[crayon-6a4717e196f27699198937/]
But Ids alone aren't all that useful - so let's add a few more columns to our query:
[crayon-6a4717e196f2c452961098/]
Now think about how you're going to execute this query plan in plain English, as a human being. You have two copies of the table: the nonclustered index (black pages) with LastAccessDate, Id:

Read more about How to Think Like the SQL Server Engine: What’s a Key Lookup? 9 comments — Join the discussion
Performance Tuning

How to Think Like the SQL Server Engine: Adding a Nonclustered Index

When we left off in the last post, our users kept running this query, and they want it to be really fast:
[crayon-6a4717e197457207130904/]
Let's pre-bake the data by creating a copy of the table sorted in a way that we can find the right rows faster:
[crayon-6a4717e19745c221360778/]
This builds a separate copy of our table (also stored in 8KB pages) that looks like this:

Read more about How to Think Like the SQL Server Engine: Adding a Nonclustered Index 21 comments — Join the discussion

How to Think Like the SQL Server Engine: The Perils of SELECT *

In our last post, we ran a query with an ORDER BY, but we only got one column in the SELECT:
[crayon-6a4717e197a4f377576673/]
The estimated cost was about $18 Query Bucks because SQL Server had to:

Scan the entire clustered index, yelling out the Id and LastAccessDate of each row
Sort that list by LastAccessDate

Read more about How to Think Like the SQL Server Engine: The Perils of SELECT * 5 comments — Join the discussion