Index Design and Access Paths

Clustered and nonclustered indexes, keys, included columns, and access paths.

113 associated posts109 primary posts

Performance Tuning

The Many Problems with SQL Server’s Index Recommendations

These days, I jump back & forth a lot between SQL Server and Postgres. (We use AWS Aurora Postgres to store SQL ConstantCare®'s data.) Whenever I come back to the sweet, sweet graphical execution plans in SQL Server Management Studio, I breathe a sigh of relief. Dang, these things are so much easier for me to interpret. It's like coming home.

Read more about The Many Problems with SQL Server’s Index Recommendations 6 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-6a70643009b52741143626/] And we had this index: [crayon-6a70643009b62710643575/] 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-6a7064301ba2f838813131/]
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-6a7064301c9b0440017762/] 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
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-6a7064301d488059265497/] 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-6a7064301e020185383978/]
But Ids alone aren't all that useful - so let's add a few more columns to our query:
[crayon-6a7064301e02b251519767/]
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-6a7064301ec21747556076/]
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-6a7064301ec2a189266721/]
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
Performance Tuning

DBA Training Plan 9: My 3 Index Guidelines

In our last episode, we used sp_BlitzIndex @Mode = 2 to get to know the contents of our database, sorted our indexes from biggest to smallest, and started asking questions about leftover backup tables that we probably didn't need to keep around anymore.

Now that you've taken out the trash, let's have a closer look at what's left. This time, run sp_BlitzIndex without a Mode parameter:
[crayon-6a7064301fc29452284157/]
You get back a prioritized list of index design issues like:

Read more about DBA Training Plan 9: My 3 Index Guidelines 1 comment — Join the discussion
Performance Tuning

DBA Training Plan 7: How SQL Server Stores Stuff in MDF Files

So far in the DBA Training Plan, we've been working hard to make sure the contents of our MDF files are backed up, corruption-free, and secured. Now, uh...what's actually inside them?

Inside each of your database data files (MDFs, although technically you can use any extension you want, even PDF or MP3), SQL Server stores your data in 8KB pages. That's kilobytes - not megabytes, not gigabytes, but just mere kilobytes.

Read more about DBA Training Plan 7: How SQL Server Stores Stuff in MDF Files 6 comments — Join the discussion
Performance Tuning

What does Azure SQL DB Automatic Index Tuning actually do, and when?

Azure SQL DB's Automatic Tuning will create and drop indexes based on your workloads. It's easy to enable - just go into your database in the Azure portal, Automatic Tuning, and then turn "on" for create and drop index:

Let's track what it does, and when. I set up Kendra Little's DDL trigger to log index changes, which produces a nice table showing who changed what indexes, when, and how:

Read more about What does Azure SQL DB Automatic Index Tuning actually do, and when? 24 comments — Join the discussion
Performance Tuning

Adventures In Foreign Keys 4: How to Index Foreign Keys

This week, we're all about foreign keys. So far, we set up the Stack Overflow database to get ready, then tried to set up relationships, and encountered cascading locking issues.
Dawn Of The Data
I don't know how long the recommendation to index your foreign keys has been a thing, but I generally find it useful to abide by, depending a bit on how they're used.

Read more about Adventures In Foreign Keys 4: How to Index Foreign Keys 6 comments — Join the discussion
Performance Tuning

How Check Constraints MIGHT Improve Your Queries and Missing Index Requests

The more SQL Server knows about your data, the better your query plans can get.

Say you've got an app that's designed to store multiple companies in a single database - but you don't actually use it that way. All of the data in a given database is actually for the same company.

Read more about How Check Constraints MIGHT Improve Your Queries and Missing Index Requests 14 comments — Join the discussion
Performance Tuning

Index Tuning Week: Getting Blocking? Play “Hot or Not.”

This week, we're all about tuning indexes. So far, we've covered Brent's 5 and 5 Rule and The D.E.A.T.H. Method. Today, let's talk about reducing blocking and deadlocking. Normally, when we think about the causes of blocking or deadlocks, we use badly written queries that modify different tables in the wrong order, resulting in a Mexican…

Read more about Index Tuning Week: Getting Blocking? Play “Hot or Not.” 9 comments — Join the discussion