简体   繁体   中英

Index scan instead of a Seek

I added a new computed column on my table:

ALTER TABLE MyTable
ADD DATAORA_STOCK AS (Data_stock + Ora_Stock)

Where Data_Stock type is char(8) and Ora_Stock type is char(6) .

After I created a new nonclustered index in this DATAORA_STOCK column:

CREATE NONCLUSTERED INDEX [IX_MyTable_DATAORA_STOCK] ON MyTable
(
    [DATAORA_STOCK] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

When I execute these 2 queries:

SELECT * FROM MyTable
WHERE DATAORA_STOCK = @Data1

And:

SELECT * FROM MyTable
WHERE DATAORA_STOCK >= @Data1

I have two different execution plan. First query seek on IX_MyTable_DATAORA_STOCK and after make a Key Lookup.

Why second perform a Scan Index on clustered index?

With OPTION(RECOMPILE) it works well and the actual (not estimated) execution plan it's right. Unfortunately I can't modify query text because it's called from application... I have updated statistics on my table but nothing change. The exact query text is:

SELECT * 
FROM MyView
WHERE DatAgg+OraAgg >= @Data1 AND DatAgg+OraAgg <= @Data2 

Where DatAgg+OraAgg is DATAORA_STOCK in original table (the view is only a projection of MyTable),and DATAORA_STOCK is a computed column.

Because the index isn't covering and it estimates that the number of rows returned by the

  WHERE DATAORA_STOCK >= @Data1

will cause so many lookups to retrieve the missing column values that it is cheaper just to scan the whole thing.

If the estimates are wrong you can try using OPTION (RECOMPILE) to get it to sniff the value of @Data1 (and if the estimates are still wrong update the statistics on that column)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM