Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is a table Scan being performed?

SELECT X.ID, X.Field4
FROM 
        #TaxInvoiceData T
INNER JOIN
        xxx X
        ON  T.Id = X.Id
        AND Field2 = @VAR     
        AND Field3 = 'S'

When I run a query a Full table scan on table X. I do not understand why because the Primary Key of Table X is

ID INT ASC
Field3 CHAR(2) ASC
Field2 DATETIME ASC  Unique Non-clustered

There is also an index on

Field2 DATETIME ASC  Non-Unique Non-clustered

Doing just

SELECT ID
FROM xxx
WHERE 
    Field2 = @VAR   
AND Field3 = 'S'

Does an Index Seek

Thanks in advance.

like image 520
Mike Avatar asked Nov 29 '11 15:11

Mike


People also ask

What causes a table scan?

A table scan is the reading of every row in a table and is caused by queries that don't properly use indexes. Table scans on large tables take an excessive amount of time and cause performance problems.

How long does a full table scan take?

With the full table scan, the query runs in about 4s. With the full index scan, it runs in about 30s.

What is a table scan what impact does it have on a database?

1) A table scan and an index scan are used when you need to retrieve all data like 90% to 100% while index seek is used when you need to retrieve data based upon some conditions like 10% of data.


1 Answers

Short answer: because the optimizer thinks it would be faster.

However, let's try to read the optimizer's mind.

Since you haven't provided full table schema, I'm going to assume that there's a clustered index on xxx.ID and that #TaxInvoiceData is a heap. You're expecting a plan where the PK index is probed for every row in #TaxInvoiceData, but you're selecting xxx.Field4 which is going to require a bookmark lookup for every match. This could result in 29,000 random I/O requests. Ouch.

Conversely, SQL Server could (and apparently is going to) just perform a larger amount of more efficient sequential I/O doing the table scan and is probably doing a speedy hash match against #TaxInvoiceData.

So what can you do? You could create a covering index including Field4. Or you could use index and join hints to force the plan you're looking for (but I suspect performance wouldn't be as good as you hope). Is this query used frequently enough that it is giving your application performance problems or are you just looking to eliminate table scans on principle? If the latter, you may find the overhead of getting rid of the scan isn't worth it in the end.


Edit:

Since you've mentioned that there's no clustered index on the table, this also may affect how efficient lookups from the index are. Unless this table is seeing extremely heavy insert activity, consider changing your PK to clustered. That alone may change the plan, and even if it doesn't it's likely to speed up other operations due to reduced overhead.

like image 160
zinglon Avatar answered Oct 06 '22 17:10

zinglon