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.