简体   繁体   中英

Where Clause Index Scan - Index Seek

I have below table:

CREATE TABLE Test
(
    Id int IDENTITY(1,1) NOT NULL,
    col1 varchar(37) NULL,
    testDate datetime NULL 
)

insert Test

select null
go 700000 

select cast(NEWID() as varchar(37))
go 300000

And below indexes:

create clustered index CIX on Test(ID)
create nonclustered index IX_RegularIndex on Test(col1)
create nonclustered index IX_RegularDateIndex on Test(testDate)

When I query on my table:

SET STATISTICS IO ON
select * from Test  where col1=NEWID()
select * from Test  where TestDate=GETDATE()

First is making index scan whereas the second index seek. I expect that both of them must make index seek. Why does the first make index scan?

在此输入图像描述

There is an implicit convert generated becuase the NEWID() function returns a value which is of uniqueidentifier datatype, and that is different than your VARCHAR datatype declared for the column.

Just try hovering your mouse over the SELECT part of the plan, where there is a "warning" sign.

Due to the fact that there is a mismatch between compared datatypes, the optimizer can't look at statistics and estimate how many rows with that NEWID() value there are in the table.

And because of the implicit convert, the optimizer thus decides that it is better to go and get all the rows (thus the SCAN ), then pass them through the FILTER operation, where it does a conversion of the value of Col1 to a uniqueidentifier datatype and then removing the additional rows that do not match the filter condition.

As opposed to GETDATE() which returns a datetime value, which is of the same datatype as your testDate column, so no datatype conversion is needed and values can be compared as they are.

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