我有下表:
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
Run Code Online (Sandbox Code Playgroud)
以下索引:
create clustered index CIX on Test(ID)
create nonclustered index IX_RegularIndex on Test(col1)
create nonclustered index IX_RegularDateIndex on Test(testDate)
Run Code Online (Sandbox Code Playgroud)
当我查询我的桌子时:
SET STATISTICS IO ON
select * from Test where col1=NEWID()
select * from Test where TestDate=GETDATE()
Run Code Online (Sandbox Code Playgroud)
首先是进行索引扫描而第二个索引是搜索.我希望他们两个都必须进行索引搜索.为什么第一个进行索引扫描?
有一个隐式转换生成,因为该NEWID()函数返回一个uniqueidentifier数据类型的值,并且与为该VARCHAR列声明的数据类型不同.
试着将鼠标悬停SELECT在计划的一部分上,那里有一个"警告"标志.
由于比较数据类型之间存在不匹配,优化程序无法查看统计信息并估计NEWID()表中包含该值的行数.
而由于隐性转换的,优化从而判定其是更好的去把所有的行(因此SCAN),然后通过它们传递FILTER操作,其中它的值转换Col1为uniqueidentifier数据类型,然后移除与过滤条件不匹配的其他行.
与之相反GETDATE(),返回的datetime值与testDate列的数据类型相同,因此不需要进行数据类型转换,可以按原样比较值.