Performance Tuning

Are nulls stored in a nonclustered index?

When you index a nullable field, are the rows with nulls stored in the index? It’s easy enough to find out by creating a table with a nullable field, and then creating an index on it:

Here’s the plan:

Yep, SQL Server stores the nulls in the index. That makes sense, really, because sooner or later, you’re going to want to find the rows with nulls, and when you’ve only got a few nulls in a big table, the index can help a lot there.

To learn more about this stuff in action, watch my free 90-minute course, How to Think Like the SQL Server Engine.

Free, 3× a week

Get my new posts by email

Three posts a week, plus a Monday roundup of the best database news from around the web.

13 comments

  1. SQL Server can also use and index for COUNT operations rather than the table, so it is critical that both have the same number of rows.

  2. Your execution plans include the number of rows and time. Where is the setting to turn that on?

    1. Aimee – that’s in the new SQL Server Management Studio 18. It’s only in preview phase, but it’s publicly available, and preview 7 has been pretty good quality for me.

      1. If you’re still on SSMS 17, it does includes counts (but not times) in the Live Query Statistics. This may be a decent substitute.

  3. Interestingly enough, Oracle made the opposite choice and does not store NULLs in the indexes (requiring some ugly tricks with indexing the results of a function if you’d like to find them).

  4. What if over 90% of a nullable field is eventually filled with NULLs and the slow statement searches using WHERE field IS NULL? (amongst other fields in the non-clustered index)

      1. Yes, good point. What I was wondering is whether to leave out those values completely from the index, even if they are used in a JOIN or WHERE clause. Or should the field be moved to the INCLUDE part of the index?

Leave a comment

Your email address will not be published. Required fields are marked *

Email me about new comments: