2013-10-29 68 views
3

我有很奇怪的問題。爲什麼我的查詢不是sargable

我有這樣的查詢,我在SQL Server 2008 R2中運行:

SELECT TOP (20) * 
FROM MyTable 
WHERE a = 0 
    AND b = 0 
    AND c = 0 

使用我的索引上MyTable的

但是這一次沒有:

SELECT TOP (20) * 
FROM MyTable 
WHERE a = 0 
    OR b = 0 
    OR c = 0 

和我想在我的程序中執行第二個查詢。如何修改第二個查詢以使用索引?

索引:

CREATE NONCLUSTERED INDEX [MyIndex] ON [dbo].[MyTable] (
[a] ASC, 
[b] ASC, 
[c] ASC 
) 
WITH (
     PAD_INDEX = OFF, 
     STATISTICS_NORECOMPUTE = OFF, 
     SORT_IN_TEMPDB = OFF, 
     IGNORE_DUP_KEY = OFF, 
     DROP_EXISTING = OFF, 
     ONLINE = OFF, 
     ALLOW_ROW_LOCKS = ON, 
     ALLOW_PAGE_LOCKS = ON 
     ) ON [PRIMARY] 
+0

它不會。它必須搜索整個索引才能找到與'LicenseDelete = 0'條件匹配的行(因爲「IRDelete」和「ColorDelete」的值可能是任何東西) –

+6

出於同樣的原因,您可以輕鬆使用手機本書尋找名字是「Martin」和姓氏「Smith」的人,但是找到名字爲「Martin」*或*姓氏「Smith」的人是更多的工作。電話簿不是按名字排序的,所以找到馬丁斯涉及閱讀整個事情。 –

+0

你是不是認爲'或'操作符總是會毀掉索引?是不是有任何方法來修復MyIndex來覆蓋where子句? – vakarami

回答

5

你不能使用一個索引對於具有條件之間or查詢。試想一下:任何一個值都可以匹配,因此索引匹配不能保證沒有其他匹配該條件的記錄。

這真的就像運行單獨的搜索,然後將它們匹配在一起。

0

爲了使用索引,SQL-Server檢查很多事情

1)如果過濾器是特區政府。

2)索引使用似然比(No的唯一記錄:總量不記錄)

3)否的記錄來獲取(如果少的記錄,也可以使用索引或其他表掃描。因爲SQL服務器發現它容易掃描整個表,而不是定位和使用指標,如果記錄的金額是巨大的。)

4)在您的查詢,因爲你正在使用OR,沒有記錄的增加,哪種情況下,sql-server發現很容易掃描整個表而不是定位電子/使用指數。如果是AND,索引使用的可能性會增加。

0

其他回答者所說的是真實的。但是,您可以使用一個技巧:

SELECT TOP (20) * 
(
select TOP(20) * 
FROM MyTable 
WHERE a = 0 

union 

SELECT TOP(20) * 
FROM MyTable 
WHERE b = 0 

union 

SELECT TOP(20) * 
FROM MyTable 
WHERE c = 0 
) 

每個單獨的子查詢都可以使用單獨的索引。所以,現在你需要的是3個獨立的索引(每個索引是a,b和c),而且你很好。