我有類似下面的查詢:在where語句中使用isnull會導致使用索引時出現問題?
SELECT t1.v3, t2.v2
FROM t1
INNER JOIN t2
ON t1.v1 = t2.v1
WHERE ISNULL(t1.DeleteFlag,'N') = 'N'
我已經制定的指標,我認爲應該導致有索引查找爲= 'N'
一部分,而是我看到一個非常昂貴的索引掃描。索引是否可能會搞亂索引的正確使用?在只有幾個可能值的列上有索引(如DeleteFlag
)?
我有類似下面的查詢:在where語句中使用isnull會導致使用索引時出現問題?
SELECT t1.v3, t2.v2
FROM t1
INNER JOIN t2
ON t1.v1 = t2.v1
WHERE ISNULL(t1.DeleteFlag,'N') = 'N'
我已經制定的指標,我認爲應該導致有索引查找爲= 'N'
一部分,而是我看到一個非常昂貴的索引掃描。索引是否可能會搞亂索引的正確使用?在只有幾個可能值的列上有索引(如DeleteFlag
)?
是的,您的WHERE子句中的任何函數調用都可能使索引無用。嘗試重寫它,以便可以利用索引:
SELECT t1.v3, t2.v2
FROM t1
INNER JOIN t2
ON t1.v1 = t2.v1
WHERE NOT t1.DeleteFlag = 'Y'
指數有道理的,如果你從查詢結果預期的數量大於表中的行的總數小得多。
很高興知道,謝謝。 – 2009-12-22 22:31:04
1)使用ISNULL是否會將掃描轉化爲掃描?是。通常將一個函數應用於列使得表達式不能使用SARG(不可搜索)。爲了使索引被考慮用於Seek操作,引擎需要知道尋找什麼值,作爲原始二進制值。只要將函數應用到列中,您要求搜索該函數的結果,因此它必須評估每行的函數以查看結果是否滿足條件。
2)在選擇性非常低(2-3個值)的柱子上有索引是否有意義?是的,但從來沒有作爲獨立的索引表達。索引tipping point將在低選擇性色譜柱上創建一個獨立索引,這只是浪費空間。但是,當使用更多的鍵組合時,像位和標誌這樣的非常低選擇性的列在索引中最左邊的鍵是非常有用的。在你的情況下,鑑於這是刪除標誌,這將是有意義的聚簇索引的第一個關鍵,因爲預計每查詢將指定'IsDeleted'條件。
我還會補充說,你應該在'deleted'標誌上不應該有NULL。
來吧 - 如果記錄是*半*或*部分*刪除? =) – 2009-12-22 23:01:35
Mark Byers的答案不起作用,這是由於SQL Server對待空值的一種非常微妙的方式。在WHERE表達式「t1.DeleteFlag ='Y'」中,如果t1.DeleteFlag爲NULL,則表達式返回NULL。所以做NOT(NULL)也返回NULL,並且這失敗了WHERE條件。試着做這個測試:
DECLARE @myvar VARCHAR(1)
SET @myvar = NULL
SELECT 'OK' WHERE ISNULL(@myvar, 'N') = 'N' -- Baseline statement. Returns OK
SELECT 'OK' WHERE NOT (@myvar = 'Y') -- Equivalent to answer above. Fails
SELECT 'OK' WHERE @myvar = 'N' OR @myvar IS NULL -- This is another way to do it. Also returns OK
第二個select語句不返回任何行,因此不等於基線語句,因此不起作用。第三條語句是編寫這個查詢的另一種方法,其中一個工作,另外一個確保可以使用該字段上的索引。
所以,這裏是一個正確的答案的問題:
SELECT t1.v3, t2.v2
FROM t1
INNER JOIN t2
ON t1.v1 = t2.v1
WHERE (t1.DeleteFlag = 'N' OR t1.DeleteFlag IS NULL)
這個的替代,這可能會產生名義上更好的表現效果,將是界定DeleteFlag場爲「NOT NULL」,給它是''(一個空字符串)的默認值。然後,查詢可以簡單地寫入而不用擔心NULL:
SELECT t1.v3, t2.v2
FROM t1
INNER JOIN t2
ON t1.v1 = t2.v1
WHERE t1.DeleteFlag = 'N'
是否有原因,DeleteFlag的數據類型不是位? – 2009-12-22 22:24:26
要回答第二個問題,在決定是否創建索引時,可能值的數目與數據如何分區並不重要。一般來說,列的選擇性越高(即每列值越多可能的行數),索引層次結構中應該越高。 – Aaronaught 2009-12-22 22:28:48
這個項目是新的,所以我不確定,但這是我在未來的潛在變化中留在腦海裏的東西。我目前的重點是解決嚴重的性能問題。如果可能的話,最好有專欄,我認爲這不會引起任何嚴重問題,是嗎? – 2009-12-22 22:29:45