2016-12-02 42 views
4

我有如下表:Where子句索引掃描 - 索引查找

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 

及以下指標:

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

當我在我的表中查詢:

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

首先是使索引掃描,而第二個索引查找。我期望他們都必須進行索引查找。爲什麼第一次進行索引掃描?

enter image description here

回答

5

有監守的NEWID()函數生成的隱式轉換返回的值是uniqueidentifier數據類型的,並且比申報的列中VARCHAR數據類型不同。

只要將鼠標懸停在計劃的SELECT部分上,那裏有「警告」標誌。

由於比較數據類型之間存在不匹配的情況,因此優化程序無法查看統計信息並估計表中存在該數值的行數。

因爲隱性轉換的同時,優化從而判定其是更好的去把所有的行(因此SCAN),然後通過FILTER操作,其中它的Col1價值的轉換通過他們到uniqueidentifier數據類型,然後刪除不符合篩選條件的其他行。

與之相對GETDATE()它返回一個datetime值,這是相同的數據類型作爲testDate列的,所以不需要數據類型轉換和因爲它們的值進行比較。

+1

有關將導致索引掃描的隱式轉換的更多信息可以在此處找到:https://www.sqlskills.com/blogs/jonathan/implicit-conversions-that-c​​ause-index-scans/ –

+0

是的,有如此多的關於隱式轉換的信息,我也會嘗試添加一些。但大多數時候這是罪魁禍首之一。 –

+0

@OmerK對不起,我誤讀了,我的意思是'VARCHAR'。 –

相關問題