1. 程式人生 > 資料庫 >通過一分鐘快速瞭解索引技巧

通過一分鐘快速瞭解索引技巧

花1分鐘時間,瞭解聚集索引,非聚集索引,聯合索引,索引覆蓋。

舉例,業務場景,使用者表,表結構為:

t_user(

uid primary key,login_name unique,passwd,login_time,age,…

);

聚集索引(clustered index):聚集索引決定資料在磁碟上的物理排序,一個表只能有一個聚集索引,一般用primary key來約束。

舉例:t_user場景中,uid上的索引

非聚集索引(non-clustered index):它並不決定資料在磁碟上的物理排序,索引上只包含被建立索引的資料,以及一個行定位符row-locator,這個行定位符,可以理解為一個聚集索引物理排序的指標,通過這個指標,可以找到行資料。

舉例,查詢年輕MM的業務需求:

select uid from t_user where age > 18 and age < 26;

age上建立的索引,就是非聚集索引。

聯合索引:多個欄位上建立的索引,能夠加速複核查詢條件的檢索

舉例,登入業務需求:

select uid,login_time from t_user where 

login_name=? and passwd=?

可以建立(login_name,passwd)的聯合索引。

聯合索引能夠滿足最左側查詢需求,例如(a,b,c)三列的聯合索引,能夠加速a | (a,b) | (a,c) 三組查詢需求。

這也就是為何不建立(passwd,login_name)這樣聯合索引的原因,業務上幾乎沒有passwd的單條件查詢需求,而有很多login_name的單條件查詢需求。

提問:

select uid,login_time from t_user where

passwd=? and login_name=?

能否命中(login_name,passwd)這個聯合索引?

回答:可以,最左側查詢需求,並不是指SQL語句的寫法必須滿足索引的順序(這是很多朋友的誤解)

索引覆蓋:被查詢的列,資料能從索引中取得,而不用通過行定位符row-locator再到row上獲取,即“被查詢列要被所建的索引覆蓋”,這能夠加速查詢速度。

舉例,登入業務需求:

select uid,login_time from t_user where

login_name=? and passwd=?

可以建立(login_name,login_time)的聯合索引,由於login_time已經建立在索引中了,被查詢的uid和login_time就不用去row上獲取資料了,從而加速查詢。

末了多說一句,登入這個業務場景,login_name具備唯一性,建這個單列索引就好。

作業:

假設訂單有三種狀態:0已下單,1已支付,2已完成

業務需求,查詢未完成的訂單,哪個SQL更快呢?

select * from order where status!=2

select * from order where status=0 or status=1

select * from order where status IN (0,1)

select * from order where status=0

union

select * from order where stauts=1

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對我們的支援。