Sql-Server

目前導列不在謂詞中時使用索引

  • October 31, 2020

當不是所有索引列都包含在謂詞中時,是否可以使用索引?在我的情況下,索引中的前導列是唯一的,並且是唯一主鍵的一部分,所以我想知道 SQL 是否仍然可以使用索引,因為它讓我印象深刻,它擁有知道其唯一性的所有資訊。

例如

CREATE TABLE x (a int, b int, c int, CONSTRAINT y PRIMARY KEY CLUSTERED (a ASC, b ASC))

SELECT * FROM x WHERE b = 1

這不使用聚集索引(它使用其他一些 NC 索引)。當然,如果我指定它的前導列。

SELECT * FROM x WHERE a = 1 AND b = 1

就我而言,索引中的前導列是唯一的……讓我印象深刻的是,它擁有知道其唯一性的所有資訊。

它不是。該主鍵不保證aorb是唯一的,只是a&的所有組合都是唯一b的。可能有很多行b = 1是正確的,可能所有行,也可能沒有。當你搜尋特定的組合a 然後 b它可以使用索引來做一個簡單的seek。

使用該表定義,您的第一個查詢就像詢問“查找字典中第二個字母為 ‘a’ 的所有單詞”。您無法通過一次搜尋來回答這個問題。您的第二個查詢就像詢問“以’aa’開頭的單詞”,該索引很容易回答。

請注意,儘管某些數據庫系統能夠執行跳過搜尋以加速第一個查詢,這在這裡會有所幫助,基本上是在尋找a=1 and b=1then a=2 and b=1thena=3 and b=1等等(它不是完全這樣,但盡可能接近) . 如果支持操作,如果數據類型為a並且指數統計數據表明的選擇性表明它可能是合適的。但是,沒有任何版本的 SQL Server 支持此操作。除非您有一個非常舊的版本(> 十年或兩年),否則 Oracle 會這樣做,SQLite 和 IIRC 都將操作稱為“跳過掃描”。進一步注意,在跳過掃描優於完整索引掃描的每種情況下,在要使用的第二列上使用索引會更有效,通常如此,這意味著雖然該功能可能會使數據庫中的某些查詢更好沒有針對它們進行優化,如果您期望這樣的查詢,即使您的 DBMS 支持跳過搜尋,您也應該通過擁有額外的索引來優化您的表。

它使用其他一些 NC 索引

為了解釋為什麼選擇和使用該特定索引而不是任何其他索引,我們需要知道該索引和所有其他索引是如何定義的,並且可能查看查詢計劃。你也沒有說索引是如何使用的——我假設它是被掃描的,而不是被用於搜尋。

只是為了說清楚:

SQL Server 可以掃描索引,但不能查找。

我們應該避免使用諸如“使用”索引之類的術語。索引查找和索引掃描之間存在很大差異。但有時非聚集索引掃描比表掃描更好(對於聚集表,我們使用術語“聚集索引掃描”而不是“表掃描”)。即,掃描索引並“跳轉到數據”以查找匹配的行。

由於您的索引是聚集索引,因此索引掃描與表掃描相同。

引用自:https://dba.stackexchange.com/questions/278763