2014-07-08 21 views
1

我有這樣的一個數字字段的表:SQLSERVER索引值

table invoices (
    inv_number  varchar(20), 
    amount   numeric(13,2), 
    amount_remaining numeric(13,2)) 

,我經常要查詢該表與零個值或非零值提取記錄。

select invnumber from invoices 
where amount_remaining=0 
... or ... 
where amount_remaining!=0 

我知道最好的soulution是添加一個預先計算的布爾字段,

但我不能碰表結構(不能添加字段)。

我只能處理索引或視圖。

在這個數字字段上添加索引只是爲了過濾零/非零值是否是一個好主意?

有什麼建議嗎?

回答

1

我知道最好的soulution是添加預先計算布爾字段

不是。那無濟於事。

select invnumber from invoices 
where amount_remaining=0 
... or ... 
where amount_remaining!=0 

該查詢不可控制。任何可能的優化都將完全取決於WHERE子句中的其他內容。除非存在可查詢表達式,否則查詢需要全面掃描,因此無法進行關於優化的討論。

在這個數字字段上添加索引只是爲了過濾零非零值是一個好主意嗎?

不,您還有條件where amount_remaining=0 ...,所以索引不起作用。

最終你有非感覺狀態。你需要滿足謂詞或否定謂詞的記錄。按照定義,這總是(不考慮三值NULL邏輯)。你問過濾索引是否有幫助。過濾後的索引將有助於WHERE子句的兩個部分之一,但從來都不是。

select invnumber from invoices 
where amount_remaining=0 and ...; 

這將通過篩選的索引與amount_remaining=0有所幫助,如果記錄的百分比,其中ammount_remaning=0

select invnumber from invoices 
where amount_remaining!=0 and ...; 

這將通過篩選的索引與amount_remaining!=0有所幫助,如果記錄的百分比,其中ammount_remaning!=0

顯然你不能有兩個標準是一個'小百分比'一次。

如果你尋找一個好的索引,你將不得不在WHERE子句的其他部分進行搜索,有些部分不能同時表達謂詞和否定OR-ed。

+0

當然,我不會在同一個查詢中使用兩個condizions(等於或不等於)。比方說,我有50%的記錄等於零,我的目標每次都能更快地訪問一半或另一半,例如:count()或sum()。 – kkk

+1

閱讀[Index Tipping Point](http://www.sqlskills.com/blogs/kimberly/category/the-tipping-point/)瞭解爲什麼沒有索引可以幫助'50%',除非[覆蓋]( https://www.simple-talk.com/sql/learn-sql-server/using-covering-indexes-to-improve-query-performance/)。你可以嘗試創建兩個覆蓋索引,一個過濾爲'= 0',另一個過濾'!= 0',看看它們是否被拾取。如果它們很窄,則應該改善掃描時間(它們仍然需要完整的NC索引掃描)。他們必須覆蓋,總和/計數查詢應該*簡單*。 –

+1

它不是非常不可靠的,因爲優化器知道在哪裏尋找:第一個零值。然而,從那時起,它必須執行一次範圍掃描。真的沒有辦法繞過它。該查詢要求所有具有零值(或非零值)的行,並且必須訪問所有這些行,無論是5行還是5mm行。額外的過濾標準可以顯着縮小該範圍,但如果唯一標準是一個字段的值,則必須執行掃描。你可以執行任何技巧來解決這個問題。 – TommCatt

0

索引不用於過濾器,是視圖將用於此。您可以使用篩選數據的條件創建視圖。

索引用於快速搜索,就像我們在書中使用索引一樣。

更新 是的,你可以給上面的列非聚集索引,它給出更快的結果。

CREATE NONCLUSTERED INDEX IX_Tablename_ColumnName 
    ON Databasename.Tablename (columnname); 

http://msdn.microsoft.com/en-IN/library/ms189280.aspx

+0

thaks回答,但它不是exaclty我在找什麼,也許我的「過濾器」的術語是混亂。我需要優化一個查詢,不只是過濾它... – kkk