Quantcast
Channel: Erik Darling – Brent Ozar Unlimited®
Viewing all articles
Browse latest Browse all 370

Index Key Column Order And Supporting Sorts

$
0
0

Whatever Man

When tuning queries that need to sort large amounts of data, sometimes it makes sense to stick the ordering elements as the leading key column(s) in your index. This allows SQL Server to easily sort your data by that column, and then access other key and included columns to satisfy other parts of the query, whether they’re joins, predicates, or selected columns.

That doesn’t mean that indexes with the sorting element first is always the best idea. Depending on how your query looks, you can sometimes put sorting elements at the end of an index definition and still have your sort be supported.

Pick It Up

Let’s start with this index:

CREATE INDEX ix_whatever ON dbo.Users (Reputation, UpVotes, DownVotes, CreationDate DESC)

If we run queries like this, the ORDER BY is unsupported by the index because it’s not the leading key column.

SELECT TOP 1000
       u.Reputation,
       u.UpVotes,
       u.DownVotes,
       u.CreationDate
FROM dbo.Users AS u
ORDER BY u.CreationDate DESC;

Slap happy

But if my query looks like this, it is supported.

SELECT TOP 1000
       u.Reputation,
       u.UpVotes,
       u.DownVotes,
       u.CreationDate
FROM dbo.Users AS u
WHERE u.Reputation = 1
      AND u.UpVotes = 0
      AND u.DownVotes = 0
ORDER BY u.CreationDate DESC;

Limited Yay

With direct equalities on each of the columns in the key of the index, we can sort by the last column in the index.

Unfortunately, this doesn’t work if we…

  • Have an incomplete WHERE clause
  • Our WHERE clause has inequalities (ranges) in it

By incomplete WHERE clause, I mean one that doesn’t utilize all of our index key columns, and by inequalities I mean >, >=, <, <=, and <>.

That means that both of these will result in a Sort operator:

SELECT TOP 1000
       u.Reputation,
       u.UpVotes,
       u.DownVotes,
       u.CreationDate
FROM dbo.Users AS u
WHERE u.Reputation = 1
ORDER BY u.CreationDate DESC;

SELECT TOP 1000
       u.Reputation,
       u.UpVotes,
       u.DownVotes,
       u.CreationDate
FROM dbo.Users AS u
WHERE u.Reputation = 1
      AND u.UpVotes = 0
ORDER BY u.CreationDate DESC;

Along with all of these:

SELECT TOP 1000
       u.Reputation,
       u.UpVotes,
       u.DownVotes,
       u.CreationDate
FROM dbo.Users AS u
WHERE u.Reputation >= 1
      AND u.UpVotes = 0
      AND u.DownVotes = 0
ORDER BY u.CreationDate DESC;

SELECT TOP 1000
       u.Reputation,
       u.UpVotes,
       u.DownVotes,
       u.CreationDate
FROM dbo.Users AS u
WHERE u.Reputation = 1
      AND u.UpVotes >= 0
      AND u.DownVotes = 0
ORDER BY u.CreationDate DESC;


SELECT TOP 1000
       u.Reputation,
       u.UpVotes,
       u.DownVotes,
       u.CreationDate
FROM dbo.Users AS u
WHERE u.Reputation = 1
      AND u.UpVotes = 0
      AND u.DownVotes >= 0
ORDER BY u.CreationDate DESC;

It would be nice if the only requirement were that the key column prior to the sorting element use an equality predicate, but that’s not so either.

For instance, this will still result in a Sort.

SELECT TOP 1000
       u.Reputation,
       u.UpVotes,
       u.DownVotes,
       u.CreationDate
FROM dbo.Users AS u
WHERE u.DownVotes = 0
ORDER BY u.CreationDate DESC;

Crud

But you do have some flexibility with other queries and other sort orders. For example, these will both result in the simple TOP plan that we saw earlier in the post. Again, the predicates need to be equalities to work.

SELECT TOP 1000
       u.Reputation,
       u.UpVotes,
       u.DownVotes,
       u.CreationDate
FROM dbo.Users AS u
WHERE u.Reputation = 1
ORDER BY u.UpVotes;

SELECT TOP 1000
       u.Reputation,
       u.UpVotes,
       u.DownVotes,
       u.CreationDate
FROM dbo.Users AS u
WHERE u.Reputation = 1
AND u.UpVotes = 0
ORDER BY u.DownVotes;

Stone Cold Wrappin’

I think this is an interesting example of how much index definitions can matter, and how a good index for one variation of a query may not be so great for another variation. There’s probably some allegory about knowing your data or something in here, too.

Thanks for reading!

Brent's presenting at the upcoming GroupBy: Getting Better Query Plans. Register free.


Viewing all articles
Browse latest Browse all 370

Trending Articles