偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

你的 SQL 還在回表查詢嗎?快給它安排上覆蓋索引

運維 數(shù)據(jù)庫運維
聚集索引的葉子節(jié)點包含完整的行數(shù)據(jù),而非聚集索引的葉子節(jié)點存儲的是每行數(shù)據(jù)的輔助索引鍵 + 該行數(shù)據(jù)對應(yīng)的聚集索引鍵(主鍵值)。

[[422248]]

本文轉(zhuǎn)載自微信公眾號「飛天小牛肉」,作者小牛肉。轉(zhuǎn)載本文請聯(lián)系飛天小牛肉公眾號。

什么是回表查詢

小伙伴們可以先看這篇文章了解下什么是聚集索引和輔助索引:Are You OK?主鍵、聚集索引、輔助索引,簡單回顧下,聚集索引的葉子節(jié)點包含完整的行數(shù)據(jù),而非聚集索引的葉子節(jié)點存儲的是每行數(shù)據(jù)的輔助索引鍵 + 該行數(shù)據(jù)對應(yīng)的聚集索引鍵(主鍵值)。

假設(shè)有張 user 表,包含 id(主鍵),name,age(普通索引)三列,有如下數(shù)據(jù):

  1. id name age 
  2. 1 Jack     18 
  3. 7 Alice     28 
  4. 10 Bob      38 
  5. 20 Carry     48 

畫一個比較簡單比較容易懂的圖來看下聚集索引和輔助索引:

  • 聚集索引:

  • 輔助索引(age):

如果查詢條件為主鍵,則只需掃描一次聚集索引的 B+ 樹即可定位到要查找的行記錄。舉個例子:

  1. select * from user where id = 7; 

查找過程如圖中綠色所示:

如果查詢條件為普通索引(輔助索引) age,則需要先查一遍輔助索引 B+ 樹,根據(jù)輔助索引鍵得到對應(yīng)的聚集索引鍵,然后再去聚集索引 B+ 樹中查找到對應(yīng)的行記錄。舉個例子:

  1. select * from user where age = 28; 

上述 select * 等同于 select id, age, name 對吧,id 是主鍵索引,age 是普通索引,而 name 并不存在于 age 索引的 B+ 樹上,所以通過 age 索引查詢到 id 和 age 的值之后,還需要去聚集索引上才能查到 name 的值。

如圖所示,第一步,查 age 輔助索引:

第二步,查聚集索引:

這就是所謂的回表查詢,因為需要掃描兩次索引 B+ 樹,所以很顯然它的性能較掃一遍索引樹更低。

什么是覆蓋索引

覆蓋索引的目的就是避免發(fā)生回表查詢,也就是說,通過覆蓋索引,只需要掃描一次 B+ 樹即可獲得所需的行記錄。

如何實現(xiàn)覆蓋索引

上文解釋過,下面這個 SQL 語句需要查詢兩次 B+ 樹:

  1. select * from user where age = 28; 

我們將其稍作修改,使其只需要查詢一次 B+ 樹:

  1. select id, age from user where age = 28; 

之前我們的返回結(jié)果是整個行記錄,現(xiàn)在我們的返回結(jié)果只需要 id 和 age。

id 是什么?主鍵索引(聚集索引),age 是什么?普通索引(輔助索引),age 索引的 B+ 樹的葉子節(jié)點存儲的是什么?輔助索引鍵 + 對應(yīng)的聚集索引鍵

所以這條 SQL 語句只需要掃描一次 age 索引的 B+ 樹就行了

這樣,結(jié)合這個例子,不知道各位有沒有受到啟發(fā),如何實現(xiàn)覆蓋索引拒絕回表查詢呢?

答:聯(lián)合索引。

我們把 age,name 設(shè)置為聯(lián)合索引:

  1. create index idx_age_name on user(`age`,`name`); 

此時 age 和 name 作為輔助索引鍵都在同一棵輔助索引的 B+ 樹上,所以只需掃描一次這個組合索引的 B+ 樹即可獲取到 id、age 和 name,這就是實現(xiàn)了索引覆蓋

覆蓋索引的常見使用場景

在下面三個場景中,可以使用覆蓋索引來進(jìn)行優(yōu)化 SQL 語句:

1)列查詢回表優(yōu)化(如上面講的例子,將單列索引 age 升級為聯(lián)合索引(age, name))

2)全表 count 查詢

舉個例子,假設(shè) user 表中現(xiàn)在只有一個索引即主鍵 id:

  1. select count(age) from user

可以用 explain 分析下這條語句,如果 Extra 字段為 Using index 時,就表示觸發(fā)索引覆蓋:

顯然現(xiàn)在是沒有觸發(fā)覆蓋索引的,我們來優(yōu)化下:將 age 列設(shè)置為索引 create index idx_age on user(age),這樣只需要查一遍 age 索引的 B+ 樹即可得到結(jié)果:

3)分頁查詢

  1. select id, age, name from user order by username limit 500, 100; 

對于這條 SQL,因為 name 字段不是索引,所以在分頁查詢需要進(jìn)行回表查詢。

Using filesort 表示沒有使用索引的排序,或者說表示在索引之外,需要額外進(jìn)行外部的排序動作??吹竭@個字段就應(yīng)該意識到你需要對這條 SQL 進(jìn)行優(yōu)化了。

使用索引覆蓋優(yōu)化:將 (age, name) 設(shè)置為聯(lián)合索引,這樣只需要查一遍 (age, name) 聯(lián)合索引的 B+ 樹即可得到結(jié)果。

 

責(zé)任編輯:武曉燕 來源: 飛天小牛肉
相關(guān)推薦

2020-02-14 18:10:40

MySQL索引數(shù)據(jù)庫

2019-04-08 14:58:36

數(shù)據(jù)庫SQL數(shù)據(jù)類型

2019-07-28 20:49:37

回表查詢索引覆蓋MySQL

2014-01-09 14:52:47

創(chuàng)意開源

2022-03-15 08:36:46

遞歸查詢SQL

2012-07-19 10:03:32

2017-09-05 12:44:15

MySQLSQL優(yōu)化覆蓋索引

2011-04-22 14:45:45

SQL索引

2024-09-24 14:32:17

RAG高級優(yōu)化Fusion

2019-11-26 09:05:32

Python機器學(xué)習(xí)深度學(xué)習(xí)

2010-11-23 10:53:40

騎驢找馬

2024-11-12 16:28:34

2010-12-20 09:26:44

SQL索引

2021-11-29 11:11:45

SQL查詢技巧

2010-07-07 11:28:12

SQL Server索

2023-11-03 08:28:19

2015-03-04 10:49:30

2024-08-26 15:17:16

2020-04-28 08:55:11

MySQL數(shù)據(jù)庫

2020-01-20 14:30:39

HTTP概念標(biāo)頭
點贊
收藏

51CTO技術(shù)棧公眾號