Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reduce index scan by avoid scaning null values

I am using SQL Server 2008 R2 and I want to add a non-clustered index on a non-unique, nullable field. My index will also have one more column included in order to avoid accessing my clustered index:

CREATE INDEX IX_My_Index 
ON MyTable (myBasicField) 
INCLUDE (myIncludedField);

In the actual data of myBasicField there will be a lot of NULLs and I was wondering if there is a way I can increase performance by not scanning these NULLs, or prevent NULL values to be stored on my index.

Thanks in advance.

like image 891
zafeiris.m Avatar asked Apr 09 '12 13:04

zafeiris.m


People also ask

Which is better index scan or seek?

An index scan or table scan is when SQL Server has to scan the data or index pages to find the appropriate records. A scan is the opposite of a seek, where a seek uses the index to pinpoint the records that are needed to satisfy the query.

Can we create index on NULL columns?

By default, relational databases ignore NULL values (because the relational model says that NULL means "not present"). So, Index does not store NULL value, consequently if you have null condition in SQL statement, related index is ignored (by default).

Does SQL Server index null values?

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.

What is the difference between table scan and index scan?

Table scan means iterate over all table rows. Index scan means iterate over all index items, when item index meets search condition, table row is retrived through index. Usualy index scan is less expensive than a table scan because index is more flat than a table.


1 Answers

With SQL Server 2008 and newer, you could use a filtered index. See an intro blog post here - syntax would be:

CREATE INDEX IX_My_Index 
ON MyTable (myBasicField) 
INCLUDE (myIncludedField)
WHERE myBasicField IS NOT NULL;

Any query that contains the same WHERE clause can take advantage of this, and the index will be a lot smaller and thus perform better if you exclude NULL values like this.

like image 99
marc_s Avatar answered Sep 20 '22 18:09

marc_s