您的位置:首頁>正文

一分鐘瞭解索引技巧|架構師之路

花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

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

聯合索引:多個欄位上建立的索引,

能夠加速覆核查詢準則的檢索

舉例, 登錄業務需求:

select uid, login_time from t_user where

login_name=? and passwd=?

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

聯合索引能夠滿足最左側查詢需求, 例如(a, b, c)三列的聯合索引, 能夠加速a | (a, b) | (a, b, 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, passwd, 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

文章來自:58架構沈劍

每天都會分享精彩的文章, 還有幽默搞笑的段子, 來放鬆心情!點一點關注吧!

還會有免費高級學習資料!

Java架構群:283943715 一起交流學習

同類文章
Next Article
喜欢就按个赞吧!!!
点击关闭提示