1. 程式人生 > 其它 >mysql索引實現原理 MySQL的索引實現原理 

mysql索引實現原理 MySQL的索引實現原理 

MySQL的索引實現原理 

 

MySQL資料庫索引總結
1. 使用索引的原由
2. 資料結構:Hash、平衡二叉樹、B樹、B+樹區別
3. 機械硬碟、固態硬碟區別
4. Myisam與Innodb B+樹的區別
5. MySQL中的索引什麼資料結構
6. B+樹中的節點到底存放多少

 


 

MySQL官方對索引的定義為:索引(Index)是幫助 MySQL 高效獲取資料的資料結構。

MySQL索引採用的資料結構有哪些?

   Hash  平衡二叉樹  B樹  B+樹區別

 

 


 Hash演算法: 

 

雜湊表(Hash table,也叫散列表),是根據關鍵碼值(Key value)而直接進行訪問的資料結構。也就是說,它通過把關鍵碼值對映到表中一個位置來訪問記錄,以加快查詢的速度。這個對映函式叫做雜湊函式

,存放記錄的陣列叫做散列表。

優點:  查詢可以直接根據key訪問
缺點:  不能進行範圍查詢
index=Hash(key)

比如 通過name 去做hash值

3 = Hash("jack")

4= Hash("Mack")

存放的是存放到陣列中

然後 查詢時候

select * from table where name = 'jack';  先計算出hash值 然後根據下表的位置就可以找到了

效率高,但是不能做範圍查詢  ( hash是個雜湊的  不能有範圍! 計算出hash值去比較的  如果不是name 是數字的話 hash值雜湊 沒法獲取正確的範圍)

 


 

平衡二叉樹:

 

平衡二叉查詢樹,又稱 AVL樹。 它除了具備二叉查詢樹的基本特徵之外,還具有一個非常重要的特點:它 的左子樹和右子樹都是平衡二叉樹,且左子樹和右子樹的深度之差的絕對值(平衡因子 ) 不超過1。 也就是說AVL樹每個節點的平衡因子只可能是-1、0和1(左子樹高度減去右子樹高度)。

 優點: 平衡二叉樹演算法基本與二叉樹查詢相同,效率比較高
 缺點: 插入操作需要旋轉,支援範圍查詢

 

 通過平衡二叉樹建立id的索引,

 平衡二叉樹,會取一箇中間值,中間值左邊成為左子樹,中間值右邊稱為右子樹

 左子樹值<中間值<右子樹值

 

 如果利用平衡二叉樹建立索引的話會生成一個檔案

 如果有一百萬條資料 ,則會有一百萬個節點。

 查詢時候,索引檔案載入到記憶體,然後進行比較。這樣容易記憶體溢位

 一般在做的時候:

 

平衡二叉樹查詢原理:

 

假設查詢10 (需要經歷4次IO操作)

1次 從硬碟中讀取4 (記憶體),判斷下10>4,取右指標

2次 從硬碟中讀取8 (記憶體),判斷下10>8,取右指標

3次 從硬碟中讀取9 (記憶體),判斷下10>,取右指標

4次 從硬碟中讀取10 (記憶體),判斷下10=10,定位到資料

 

查詢四次!

 

平衡二叉樹 查詢效率還可以,缺點:雖然支援範圍查詢,但是迴旋查詢效率低。

規律:如果樹的高度越高,那麼查詢IO次數會越多。

 


 

資料結構B樹 
維基百科對B樹的定義為“在電腦科學中,B樹(B-tree)是一種樹狀資料結構,它能夠儲存資料、對其進行排序並允許以O(log n)的時間複雜度執行進行查詢、順序讀取、插入和刪除的資料結構。B樹,概括來說是一個節點可以擁有多於2個子節點的二叉查詢樹。與自平衡二叉查詢樹不同,B-樹為系統最優化大塊資料的讀和寫操作。B-tree演算法減少定位記錄時所經歷的中間過程,從而加快存取速度。普遍運用在資料庫和檔案系統。”
因為B樹節點元素比平衡二叉樹要多,所以B樹資料結構相比平衡二叉樹資料結構實現減少磁碟IO的操作。

B樹對於平衡二叉樹做改進

平衡二叉樹高度越高 查詢IO次數越多

規律: 如果樹的高度越高,查詢次數越多。如何減少IO次數?  B樹在平衡二叉樹中,減少樹的高度。

明顯高度低了

假設查詢10 (需要經歷3次IO操作)

1次 從硬碟中讀取4 (記憶體),判斷下10>4,取右指標

2次 從硬碟中讀取6,8 (記憶體),判斷下10>8,取右指標

3次 從硬碟中讀取9,10 (記憶體),判斷下10=10 定位到資料

B樹比平衡二叉樹減少了一次IO操作

結論: B樹查詢效率比平衡二叉樹高,因為B樹節點中可以有多個元素,從而減少樹的高度,減少IO操作,從而提高查詢效率。但是範圍查詢效率依然比較低

 


 

 資料結構B+樹 

B+樹相比B樹,繼承了B數的特徵。新增葉子節點與非葉子節點關係,葉子節點中包含了key和value,非葉子節點中只是包含了key,不包含value。
所有相鄰的葉子節點包含非葉子節點,使用連結串列進行結合,有一定順序排序,從而範圍查詢效率非常高

 

通過非葉子節點查詢葉子節點獲取對應的value。範圍查詢的效率提高!

缺點: 因為有冗餘的節點資料,會比較佔硬碟。

結合索引:

key就是建立索引的值

value是地址 

 

B+樹 解決範圍查詢問題、減少IO查詢的操

 


 

 結合資料庫,B+樹是怎麼玩起來的?

 MyISAM和InnoDB對B-Tree索引不同的實現方式 主鍵索引: MyISAM引擎使用B+Tree作為索引結構,葉節點的data域存放的是資料記錄的地址。

下圖是MyISAM主鍵索引的

這裡設表一共有三列,假設我們以Col1為主鍵,圖myisam1是一個MyISAM表的主索引(Primary key)示意。可以看出

    

  上圖: 以主鍵建立的索引 

             葉子節點的key就是主鍵id    value定位到資料庫中哪一行的資料的地址

 

區別: 

 InnoDB直接存放的資料不是地址是資料,它的value直接就是那一行的資料(但是有大小限制的不可能存放無限制的)!

 而MyISam是地址,再通過地址查詢行數。

 

MyISAM和InnoDB對B-Tree索引不同的實現方式然InnoDB也使用B+Tree作為索引結構,但具體實現方式卻與MyISAM截然不同.
MyISAM索引檔案和資料檔案是分離的,索引檔案僅儲存資料記錄的地址。而在InnoDB中,表資料檔案本身就是按B+Tree組織的一個索引結構,這棵樹的葉節點data域儲存了完整的資料記錄。這個索引的key是資料表的主鍵,因此InnoDB表資料檔案本身就是主索引。

 

 

 

索引檔案最終是存放在硬碟上的,不是記憶體哈。有IO操作的

 

 B+樹相比B樹,新增葉子節點與非葉子節點關係,葉子節點中包含了key和value,非葉子節點中只是包含了key,不包含value。

所有相鄰的葉子節點包含非葉子節點,使用連結串列進行結合,有一定順序排序,從而範圍查詢效率非常高
注意:MyISAM和InnoDB對B-Tree索引不同的實現方式
MyISAM底層使用B+樹 葉子節點的value對應存放行數的地址,在通過行數定位到資料。
InnoDB底層使用B+樹,葉子節點的value對應存放是行的data資料,相比MyISAM效率要高一些,但是比較佔硬碟記憶體大小。

 

最終形成了一個索引檔案,是存放在硬碟的。每次查詢時候都是在讀硬碟。

 

選擇B+樹的原因:

B+樹索引具有範圍查詢和字首查詢的能力,相當於二分查詢。

Hash索引只能支援等於查詢,無法支援範圍查詢

 

 


 

索引檔案如何檢視

預設資料與索引檔案位置: /var/lib/mysql

MyISAM引擎的檔案:
.myd 即 my data,表資料檔案
.myi 即my index,索引檔案
.log 日誌檔案。

InnoDB引擎的檔案:
採用表空間(tablespace)來管理資料,儲存表資料和索引,
InnoDB資料庫檔案(即InnoDB檔案集,ib-file set):
ibdata1、ibdata2等:系統表空間檔案,儲存InnoDB系統資訊和使用者資料庫表資料和索引,所有表共用。
.ibd檔案:單表表空間檔案,每個表使用一個表空間檔案(file per table),存放使用者資料庫表資料和索引。

 

結合圖形化介面:

有好多引擎

 進入/var/lib/mysql/test   (tes為資料庫名稱)

  

 

    


 

對於SQL查詢優化 

開啟慢查詢日誌,可以讓MySQL記錄下查詢超過指定時間的語句,通過定位分析效能的瓶頸,才能更好的優化資料庫系統的效能。
先捕獲低效SQL→慢查詢優化方案→慢查詢優化原則 

MySQL資料庫配置慢查詢
引數說明:
slow_query_log 慢查詢開啟狀態
slow_query_log_file 慢查詢日誌存放的位置(這個目錄需要MySQL的執行帳號的可寫許可權,一般設定為MySQL的資料存放目錄)
long_query_time 查詢超過多少秒才記錄
1.查詢慢查詢配置
show variables like 'slow_query%';
2.查詢慢查詢限制時間
show variables like 'long_query_time';
3.將 slow_query_log 全域性變數設定為“ON”狀態
set global slow_query_log='ON';
4.查詢超過1秒就記錄
set global long_query_time=1;
5.查詢cat /var/lib/mysql/localhost-slow.log
service mysqld restart

 

1、

2、

預設10s沒有響應的話 就會記錄到下面的檔案中去:

 

 

 正確步驟是

 第一步中開啟慢查詢 ON, 將 slow_query_log 全域性變數設定為“ON”狀態。 

  set global slow_query_log='ON';

 然後再去修改時間秒數,查詢超過1秒就記錄 set global long_query_time=1;

 關閉當前連線,然後重新連線

 

檢視此檔案:

 

 

 如果滿足條件 查詢時間很慢 會記錄在這裡

 

 


 

關於索引失效問題

索引為什麼會失效?注意那些事項?

1.索引無法儲存null值,where num is null  全表掃描
2.如果條件中有or,即使其中有條件帶索引也不會使用(這也是為什麼儘量少用or的原因)
要想使用or,又想讓索引生效,只能將or條件中的每個列都加上索引
3.對於多列索引,不是使用的第一部分,則不會使用索引
4.like查詢以%開頭
5.如果列型別是字串,那一定要在條件中將資料使用引號引用起來,否則不使用索引
6.如果mysql估計使用全表掃描要比使用索引快,則不使用索引

7.避免where字句中 != 或 <> 

8.in 和 not in 也要慎用 

   建立表:

   

CREATE TABLE `user_details` (
  `id` int(11) ,
  `user_name` varchar(50) DEFAULT NULL,
  `user_phone` varchar(11) DEFAULT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

  主鍵索引: id   

 

  建立普通索引:

  ALTER TABLE `user_details` ADD INDEX user_name_index ( `user_name` )

 

 查看錶結構:    

 DESC user_details;      看到有兩個索引id   和 user_name

 

 

 插入資料:

 

insert into user_details values(1,'a1','12312312');

insert into user_details values(2,'a2','12312123');

insert into user_details values(3,'a3','15924134');

insert into user_details values(4,'a4','23423423');

insert into user_details values(5,'a5','12352343');

insert into user_details values(6,'a6','35634523');

 

 全表掃描:

優化查詢時候 儘量使用索引欄位進行查詢   

 

 

兩個索引都沒有用上

 

 

  like 不能用到索引哦

  

 普通索引 百分號放後面時候 like 可以用到索引

 

 

 主鍵索引不存在模糊查詢的  本身就唯一 不存在多個

  

如果列型別是字串,一定要在條件中將資料使用引號,否則用不到索引

  

 

  1. 索引無法儲存null值
  2. 前導模糊查詢不能利用索引(like '%XX'或者like '%XX%')
  3. 索引失效的幾種情況

         1.如果條件中有or,即使其中有條件帶索引也不會使用(這也是為什麼儘量少用or的原因)要想使用or,又想讓索引生效,只能將or條件中的每個列都加上索引

         2.對於多列索引,不是使用的第一部分,則不會使用索引

         3.like查詢以%開頭

         4.如果列型別是字串,那一定要在條件中將資料使用引號引用起來,否則不使用索引

         5.如果mysql估計使用全表掃描要比使用索引快,則不使用索引

 

 

 

聯合索引為什麼需要遵循左字首原則?

  建立表:

CREATE TABLE `user_details` (
  `id` int(11) ,
  `user_name` varchar(50) ,
  `user_phone` varchar(11) DEFAULT NULL,
  PRIMARY KEY (id,user_name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 主鍵是id   user_name   

 

  

insert into user_details values(1,'a1','12312312');

insert into user_details values(1,'a2','12312123');

可以插入成功! 聯合主鍵索引  id+user_name保證唯一就OK了!  多個

 

插入如下資料:

  

insert into user_details values(1,'a1','12312123');

insert into user_details values(1,'a2','12312123');


insert into user_details values(2,'a1','12312123');

insert into user_details values(2,'a2','12312123');


insert into user_details values(3,'a1','12312123');

insert into user_details values(3,'a2','12312123');

 

如果只有一個條件 user_name

 

 

 聯合主鍵索引中: 左字首指的就是第一個索引 id  

 聯合主鍵索引中,必須要加上左字首,才會生效?

  

 葉子節點分析 連結串列, 

 [1+a1] ---> [1+a2] ---->  [2+a1]---> [2+a2]--->[3+a1]--->[3+a2]

  

 select * from user_deatils where id = 1 and user_name = 'a1'

 通過字首就可以查詢到葉子,知道有個範圍了  “範圍”是個亮點!!!

 如果不帶第一個索引 查詢時候 會因為不知道第一個索引是什麼,只有第二個,而進行全表查詢

 因為索引底層採用B+樹葉子節點順序排列,必須通過左字首索引才能定位到具體的節點範圍。

  

聯合主鍵索引:

 

 

 分表分庫能夠提高資料查詢效率?

  

分表分庫為什麼提高查詢的效率?因為會將一張表的資料拆分成多個n張表進行存放,讓後在使用第三方中介軟體(MyCat或者Sharding-JDBC)並行同時查詢,讓後在交給第三方中間進行組合返回給客戶端。

 

 

同時操作,就跟多執行緒一樣。 

分表分庫為什麼提高查詢的效率?因為會將一張表的資料拆分成多個n張表進行存放,讓後在使用第三方中介軟體(MyCat或者Sharding-JDBC)並行同時查詢,讓後在交給第三方中間進行組合返回給客戶端。

 

 

不適合建索引的欄位


 

索引的建立必須慎重,對每個索引的必要性都應該經過仔細分析,要有建立的依據。 
因為太多的索引與不充分、不正確的索引對效能都毫無益處:在表上建立的每個索引都會增加儲存開銷,索引對於插入、刪除、更新操作也會增加處理上的開銷。 另外,過多的複合索引,在有單欄位索引的情況下,一般都是沒有存在價值的;相反,還會降低資料增加刪除時的效能,特別是對頻繁更新的表來說,負面影響更大。 
總的來說,小型表肯定不建索引, 
或者資料庫記錄在億條資料級以上,還是建議使用非關係型資料庫。 
還有些特殊欄位的資料庫,比如BLOB,CLOB欄位肯定也不適合建索引。 

 

從以下幾個方面分析:

1. 建立索引

也不是什麼情況都非得建索引不可,比如性別可能就只有兩個值,建索引不僅沒什麼優勢,還會影響到更新速度,這被稱為過度索引。

2. 複合索引

select * from users where area=’beijing’ and age=22; 在area和age上分別建立單個索引的話,由於mysql查詢每次只能使用一個索引,這樣已經相對不做索引時全表掃描提高了效率。但是如果在area、age兩列上建立複合索引的話將帶來更高的效率。如果我們建立了(area, age, salary)的複合索引,那麼其實相當於建立了(area,age,salary)、(area,age)、(area)三個索引,這被稱為最佳左字首 特性。因此我們在建立複合索引時應該將最常用作限制條件的列放在最左邊,依次遞減。

注1:在mysql中執行查詢時,只能使用一個索引,如果我們在lname,fname,age上分別建索引,執行查詢時,只能使用一個索引,mysql會選擇一個最嚴格(獲得結果集記錄數最少)的索引。

注2:在建立多列索引時,要根據業務需求,where子句中使用最頻繁的一列放在最左邊。

MySQL 最左字首匹配原則(即建立聯合索引的使用)

1、在mysql建立聯合索引時會遵循最左字首匹配的原則,即最左優先,在檢索資料時從聯合索引的最左邊開始匹配,示例:
對列col1、列col2和列col3建一個聯合索引

KEY index_col1_col2_col3 on test(col1,col2,col3);

聯合索引 index_col1_col2_col3 實際建立了(col1)、(col1,col2)、(col,col2,col3)三個索引。

SELECT * FROM table WHERE col1="1" AND clo2="2" AND clo4="4"

上面這個查詢語句執行時會依照最左字首匹配原則,檢索時會使用索引(col1,col2)進行資料匹配。索引的欄位可以是任意順序的。

使用聯合索引的好處

  • 減少開銷。每多一個索引,都會增加寫操作的開銷和磁碟空間的開銷。對於大量資料的表,使用聯合索引會大大的減少開銷!
  • 效率高。索引列越多,通過索引篩選出的資料越少。

3.索引不會包含有NULL值的列

只要列中包含有NULL值都將不會被包含在索引中,複合索引中只要有一列含有NULL值,那麼這一列對於此複合索引就是無效的。所以我們在資料庫設計時不要讓欄位的預設值為NULL。

4.使用短索引

對串列進行索引,如果可能應該指定一個字首長度。例如,如果有一個CHAR(255)的 列,如果在前10 個或20 個字元內,多數值是惟一的,那麼就不要對整個列進行索引。短索引不僅可以提高查詢速度而且可以節省磁碟空間和I/O操作。

5.排序的索引問題

mysql查詢只使用一個索引,因此如果where子句中已經使用了索引的話,那麼order by中的列是不會使用索引的。因此資料庫預設排序可以符合要求的情況下不要使用排序操作;儘量不要包含多個列的排序,如果需要最好給這些列建立複合索引。

6.like語句操作

一般情況下不鼓勵使用like操作,如果非使用不可,如何使用也是一個問題。like “%a%” 不會使用索引而like “aaa%”可以使用索引。

7.不要在列上進行運算

select * from users where YEAR(adddate)

8.不使用NOT IN和操作

NOT IN和操作都不會使用索引將進行全表掃描。NOT IN可以NOT EXISTS代替,id3則可使用id>3 or id

 

 

索引的一些分類:

1.普通索引index :加速查詢
2.唯一索引
    主鍵索引:primary key :加速查詢+約束(不為空且唯一)
    唯一索引:unique:加速查詢+約束 (唯一)
3.聯合索引
    -primary key(id,name):聯合主鍵索引
    -unique(id,name):聯合唯一索引
    -index(id,name):聯合普通索引
4.全文索引fulltext :用於搜尋很長一篇文章的時候,效果最好。
5.空間索引spatial :瞭解就好,幾乎不用

 

談一談InnoDb索引的使用,一直以來專案開發用的都是InnoD引擎,而innodb使用的是b+tree進行儲存,資料存放在子節點上

多列索引如何決定順序

  • 選擇性高的放在最左邊
  • 把長度小的列放在左側(單頁可以容納的資料更多,減少io)
  • 使用最頻繁的放在左側

  組合索引的生效原則是  從前往後依次使用生效,如果中間某個索引沒有使用,那麼斷點前面的索引部分起作用,斷點後面的索引沒有起作用

 

比如

where a=3 and b=45 and c=5 .... 這種三個索引順序使用中間沒有斷點,全部發揮作用;
where a=3 and c=5... 這種情況下b就是斷點,a發揮了效果,c沒有效果
where b=3 and c=4... 這種情況下a就是斷點,在a後面的索引都沒有發揮作用,這種寫法聯合索引沒有發揮任何效果;
where b=45 and a=3 and c=5 .... 這個跟第一個一樣,全部發揮作用,abc只要用上了就行,跟寫的順序無關

(a,b,c) 三個列上加了聯合索引(是聯合索引 不是在每個列上單獨加索引)

注:,  (a,b,c)多列索引和 (a,c,b)是不一樣的

複製程式碼
(0)    select * from mytable where a=3 and b=5 and c=4;
abc三個索引都在where條件裡面用到了,而且都發揮了作用
(1)    select * from mytable where  c=4 and b=6 and a=3;
這條語句列出來只想說明 mysql沒有那麼笨,where裡面的條件順序在查詢之前會被mysql自動優化,效果跟上一句一樣
(2)    select * from mytable where a=3 and c=7;
a用到索引,b沒有用,所以c是沒有用到索引效果的
(3)    select * from mytable where a=3 and b>7 and c=3;
a用到了,b也用到了,c沒有用到,這個地方b是範圍值,也算斷點,只不過自身用到了索引
(4)    select * from mytable where b=3 and c=4;
因為a索引沒有使用,所以這裡 bc都沒有用上索引效果
(5)    select * from mytable where a>4 and b=7 and c=9;
a用到了  b沒有使用,c沒有使用
(6)    select * from mytable where a=3 order by b;
a用到了索引,b在結果排序中也用到了索引的效果,前面說了,a下面任意一段的b是排好序的
(7)    select * from mytable where a=3 order by c;
a用到了索引,但是這個地方c沒有發揮排序效果,因為中間斷點了,使用 explain 可以看到 filesort
(8)    select * from mytable where b=3 order by a;
b沒有用到索引,排序中a也沒有發揮索引效果

 

索引是一種資料結構:

 

 索引採用的B+樹,為何用B+樹呢?

 

引入二叉查詢樹:這個約束性很差 可能會出現連結串列的樣子!

 

   

 

 

平衡二分查詢樹:

兩種   種類1: AVL樹 插入時候會左選裝,檢查平衡因子,高度差,不滿足時候,做一些操作,讓其平衡。    

 

 

(上圖中資料區要麼存地址,要麼存資料。 注意標註的是磁碟塊)

 

 

種類2:

紅黑樹 (略)

 

二叉樹缺陷:

 1. 搜尋效率問題:樹的深度決定了搜尋時候IO的次數。

 2. 內容數量問題: 

   每一個磁碟塊(節點/頁)儲存的關鍵字數量太少了。

  沒有利用好作業系統和磁碟的資料互動特性,作業系統和磁碟進行資料互動.也沒有利用好磁碟IO預讀能力(空間區域性性原理)

     備註:交換的單位是頁 4k (ssd 4k對齊)做一次IO 載入4k 浪費資源!

  

多路平衡查詢樹:

  

路: 叉 分叉 關鍵字的個數 等於 路-1 比如:小於17 大於25 介於之間

 

 

B樹的變種,MySQL的B+樹:

 

 

 

B+樹和B-樹的區別

 B+樹的關鍵字搜尋採用閉合區間

 B+樹的非葉子節點不儲存資料相關資訊,只儲存關鍵字和子節點引用。

 B+樹關鍵字對應的資料儲存在葉子節點中

 B+樹葉子節點是順序排列的,並且相鄰節點具有順序引用的關係。

 

    MySQL引擎: 一個庫中不同的表可以用不同的儲存引擎   MyISAM:

 

 

 

 

 

 

 

InnoDB:

 

 

 

 

 

 

 InnoDB VS MyISAM:

 

 

 

索引的幾大原則:   1.離散型越高選擇性越好  對索引的關鍵字進行(計算)對比,一定是從左往右依次進行,且不可以跳過。

 

2. 聯合索引

  單列索引: 節點中關鍵字【name】

  聯合索引: 節點中關鍵字 【name, sex, mobile】

 注:  單列索引是特殊的聯合索引

 

聯合索引列選擇原則:

  1.經常用的列優先(最左匹配原則)

  2.離散度高的優先(離散度高原則)

  3.寬度小的列優先(最少空間原則)

 

 

最左匹配原則:

比如經常用到:

SELECT * FROM `user` WHERE `name` = "";
SELECT * FROM `user` WHERE `name`= "" AND mobile = ""

則應該這樣建立索引:

 

 

 

 create index idx_name_mobile on user (name, mobile)

 

覆蓋索引:

  • 解釋一: 就是select的資料列只用從索引中就能夠取得,不必從資料表中讀取,換句話說查詢列要被所使用的索引覆蓋。
  • 解釋二: 索引是高效找到行的一個方法,當能通過檢索索引就可以讀取想要的資料,那就不需要再到資料表中讀取行了。如果一個索引包含了(或覆蓋了)滿足查詢語句中欄位與條件的資料就叫做覆蓋索引。
  • 解釋三:是非聚集組合索引的一種形式,它包括在查詢裡的Select、Join和Where子句用到的所有列(即建立索引的欄位正好是覆蓋查詢語句[select子句]與查詢條件[Where子句]中所涉及的欄位,也即,索引包含了查詢正在查詢的所有資料)。

 

 

即: 如果查詢的列,通過索引項的資訊可以直接返回,則改索引稱為該sql的覆蓋索引。

 

 

 轉載自  https://www.cnblogs.com/toov5/p/10340349.html

MySQL資料庫索引總結
1. 使用索引的原由
2. 資料結構:Hash、平衡二叉樹、B樹、B+樹區別
3. 機械硬碟、固態硬碟區別
4. Myisam與Innodb B+樹的區別
5. MySQL中的索引什麼資料結構
6. B+樹中的節點到底存放多少

 


 

MySQL官方對索引的定義為:索引(Index)是幫助 MySQL 高效獲取資料的資料結構。

MySQL索引採用的資料結構有哪些?

   Hash  平衡二叉樹  B樹  B+樹區別

 

 


 Hash演算法: 

 

雜湊表(Hash table,也叫散列表),是根據關鍵碼值(Key value)而直接進行訪問的資料結構。也就是說,它通過把關鍵碼值對映到表中一個位置來訪問記錄,以加快查詢的速度。這個對映函式叫做雜湊函式,存放記錄的陣列叫做散列表。

優點:  查詢可以直接根據key訪問
缺點:  不能進行範圍查詢
index=Hash(key)

比如 通過name 去做hash值

3 = Hash("jack")

4= Hash("Mack")

存放的是存放到陣列中

然後 查詢時候

select * from table where name = 'jack';  先計算出hash值 然後根據下表的位置就可以找到了

效率高,但是不能做範圍查詢  ( hash是個雜湊的  不能有範圍! 計算出hash值去比較的  如果不是name 是數字的話 hash值雜湊 沒法獲取正確的範圍)

 


 

平衡二叉樹:

 

平衡二叉查詢樹,又稱 AVL樹。 它除了具備二叉查詢樹的基本特徵之外,還具有一個非常重要的特點:它 的左子樹和右子樹都是平衡二叉樹,且左子樹和右子樹的深度之差的絕對值(平衡因子 ) 不超過1。 也就是說AVL樹每個節點的平衡因子只可能是-1、0和1(左子樹高度減去右子樹高度)。

 優點: 平衡二叉樹演算法基本與二叉樹查詢相同,效率比較高
 缺點: 插入操作需要旋轉,支援範圍查詢

 

 通過平衡二叉樹建立id的索引,

 平衡二叉樹,會取一箇中間值,中間值左邊成為左子樹,中間值右邊稱為右子樹

 左子樹值<中間值<右子樹值

 

 如果利用平衡二叉樹建立索引的話會生成一個檔案

 如果有一百萬條資料 ,則會有一百萬個節點。

 查詢時候,索引檔案載入到記憶體,然後進行比較。這樣容易記憶體溢位

 一般在做的時候:

 

平衡二叉樹查詢原理:

 

假設查詢10 (需要經歷4次IO操作)

1次 從硬碟中讀取4 (記憶體),判斷下10>4,取右指標

2次 從硬碟中讀取8 (記憶體),判斷下10>8,取右指標

3次 從硬碟中讀取9 (記憶體),判斷下10>,取右指標

4次 從硬碟中讀取10 (記憶體),判斷下10=10,定位到資料

 

查詢四次!

 

平衡二叉樹 查詢效率還可以,缺點:雖然支援範圍查詢,但是迴旋查詢效率低。

規律:如果樹的高度越高,那麼查詢IO次數會越多。

 


 

資料結構B樹 
維基百科對B樹的定義為“在電腦科學中,B樹(B-tree)是一種樹狀資料結構,它能夠儲存資料、對其進行排序並允許以O(log n)的時間複雜度執行進行查詢、順序讀取、插入和刪除的資料結構。B樹,概括來說是一個節點可以擁有多於2個子節點的二叉查詢樹。與自平衡二叉查詢樹不同,B-樹為系統最優化大塊資料的讀和寫操作。B-tree演算法減少定位記錄時所經歷的中間過程,從而加快存取速度。普遍運用在資料庫和檔案系統。”
因為B樹節點元素比平衡二叉樹要多,所以B樹資料結構相比平衡二叉樹資料結構實現減少磁碟IO的操作。

B樹對於平衡二叉樹做改進

平衡二叉樹高度越高 查詢IO次數越多

規律: 如果樹的高度越高,查詢次數越多。如何減少IO次數?  B樹在平衡二叉樹中,減少樹的高度。

明顯高度低了

假設查詢10 (需要經歷3次IO操作)

1次 從硬碟中讀取4 (記憶體),判斷下10>4,取右指標

2次 從硬碟中讀取6,8 (記憶體),判斷下10>8,取右指標

3次 從硬碟中讀取9,10 (記憶體),判斷下10=10 定位到資料

B樹比平衡二叉樹減少了一次IO操作

結論: B樹查詢效率比平衡二叉樹高,因為B樹節點中可以有多個元素,從而減少樹的高度,減少IO操作,從而提高查詢效率。但是範圍查詢效率依然比較低

 


 

 資料結構B+樹 

B+樹相比B樹,繼承了B數的特徵。新增葉子節點與非葉子節點關係,葉子節點中包含了key和value,非葉子節點中只是包含了key,不包含value。
所有相鄰的葉子節點包含非葉子節點,使用連結串列進行結合,有一定順序排序,從而範圍查詢效率非常高

 

通過非葉子節點查詢葉子節點獲取對應的value。範圍查詢的效率提高!

缺點: 因為有冗餘的節點資料,會比較佔硬碟。

結合索引:

key就是建立索引的值

value是地址 

 

B+樹 解決範圍查詢問題、減少IO查詢的操

 


 

 結合資料庫,B+樹是怎麼玩起來的?

 MyISAM和InnoDB對B-Tree索引不同的實現方式 主鍵索引: MyISAM引擎使用B+Tree作為索引結構,葉節點的data域存放的是資料記錄的地址。

下圖是MyISAM主鍵索引的

這裡設表一共有三列,假設我們以Col1為主鍵,圖myisam1是一個MyISAM表的主索引(Primary key)示意。可以看出

    

  上圖: 以主鍵建立的索引 

             葉子節點的key就是主鍵id    value定位到資料庫中哪一行的資料的地址

 

區別: 

 InnoDB直接存放的資料不是地址是資料,它的value直接就是那一行的資料(但是有大小限制的不可能存放無限制的)!

 而MyISam是地址,再通過地址查詢行數。

 

MyISAM和InnoDB對B-Tree索引不同的實現方式然InnoDB也使用B+Tree作為索引結構,但具體實現方式卻與MyISAM截然不同.
MyISAM索引檔案和資料檔案是分離的,索引檔案僅儲存資料記錄的地址。而在InnoDB中,表資料檔案本身就是按B+Tree組織的一個索引結構,這棵樹的葉節點data域儲存了完整的資料記錄。這個索引的key是資料表的主鍵,因此InnoDB表資料檔案本身就是主索引。

 

 

 

索引檔案最終是存放在硬碟上的,不是記憶體哈。有IO操作的

 

 B+樹相比B樹,新增葉子節點與非葉子節點關係,葉子節點中包含了key和value,非葉子節點中只是包含了key,不包含value。

所有相鄰的葉子節點包含非葉子節點,使用連結串列進行結合,有一定順序排序,從而範圍查詢效率非常高
注意:MyISAM和InnoDB對B-Tree索引不同的實現方式
MyISAM底層使用B+樹 葉子節點的value對應存放行數的地址,在通過行數定位到資料。
InnoDB底層使用B+樹,葉子節點的value對應存放是行的data資料,相比MyISAM效率要高一些,但是比較佔硬碟記憶體大小。

 

最終形成了一個索引檔案,是存放在硬碟的。每次查詢時候都是在讀硬碟。

 

選擇B+樹的原因:

B+樹索引具有範圍查詢和字首查詢的能力,相當於二分查詢。

Hash索引只能支援等於查詢,無法支援範圍查詢

 

 


 

索引檔案如何檢視

預設資料與索引檔案位置: /var/lib/mysql

MyISAM引擎的檔案:
.myd 即 my data,表資料檔案
.myi 即my index,索引檔案
.log 日誌檔案。

InnoDB引擎的檔案:
採用表空間(tablespace)來管理資料,儲存表資料和索引,
InnoDB資料庫檔案(即InnoDB檔案集,ib-file set):
ibdata1、ibdata2等:系統表空間檔案,儲存InnoDB系統資訊和使用者資料庫表資料和索引,所有表共用。
.ibd檔案:單表表空間檔案,每個表使用一個表空間檔案(file per table),存放使用者資料庫表資料和索引。

 

結合圖形化介面:

有好多引擎

 進入/var/lib/mysql/test   (tes為資料庫名稱)

  

 

    


 

對於SQL查詢優化 

開啟慢查詢日誌,可以讓MySQL記錄下查詢超過指定時間的語句,通過定位分析效能的瓶頸,才能更好的優化資料庫系統的效能。
先捕獲低效SQL→慢查詢優化方案→慢查詢優化原則 

MySQL資料庫配置慢查詢
引數說明:
slow_query_log 慢查詢開啟狀態
slow_query_log_file 慢查詢日誌存放的位置(這個目錄需要MySQL的執行帳號的可寫許可權,一般設定為MySQL的資料存放目錄)
long_query_time 查詢超過多少秒才記錄
1.查詢慢查詢配置
show variables like 'slow_query%';
2.查詢慢查詢限制時間
show variables like 'long_query_time';
3.將 slow_query_log 全域性變數設定為“ON”狀態
set global slow_query_log='ON';
4.查詢超過1秒就記錄
set global long_query_time=1;
5.查詢cat /var/lib/mysql/localhost-slow.log
service mysqld restart

 

1、

2、

預設10s沒有響應的話 就會記錄到下面的檔案中去:

 

 

 正確步驟是

 第一步中開啟慢查詢 ON, 將 slow_query_log 全域性變數設定為“ON”狀態。 

  set global slow_query_log='ON';

 然後再去修改時間秒數,查詢超過1秒就記錄 set global long_query_time=1;

 關閉當前連線,然後重新連線

 

檢視此檔案:

 

 

 如果滿足條件 查詢時間很慢 會記錄在這裡

 

 


 

關於索引失效問題

索引為什麼會失效?注意那些事項?

1.索引無法儲存null值,where num is null  全表掃描
2.如果條件中有or,即使其中有條件帶索引也不會使用(這也是為什麼儘量少用or的原因)
要想使用or,又想讓索引生效,只能將or條件中的每個列都加上索引
3.對於多列索引,不是使用的第一部分,則不會使用索引
4.like查詢以%開頭
5.如果列型別是字串,那一定要在條件中將資料使用引號引用起來,否則不使用索引
6.如果mysql估計使用全表掃描要比使用索引快,則不使用索引

7.避免where字句中 != 或 <> 

8.in 和 not in 也要慎用 

   建立表:

   

CREATE TABLE `user_details` (
  `id` int(11) ,
  `user_name` varchar(50) DEFAULT NULL,
  `user_phone` varchar(11) DEFAULT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

  主鍵索引: id   

 

  建立普通索引:

  ALTER TABLE `user_details` ADD INDEX user_name_index ( `user_name` )

 

 查看錶結構:    

 DESC user_details;      看到有兩個索引id   和 user_name

 

 

 插入資料:

 

insert into user_details values(1,'a1','12312312');

insert into user_details values(2,'a2','12312123');

insert into user_details values(3,'a3','15924134');

insert into user_details values(4,'a4','23423423');

insert into user_details values(5,'a5','12352343');

insert into user_details values(6,'a6','35634523');

 

 全表掃描:

優化查詢時候 儘量使用索引欄位進行查詢   

 

 

兩個索引都沒有用上

 

 

  like 不能用到索引哦

  

 普通索引 百分號放後面時候 like 可以用到索引

 

 

 主鍵索引不存在模糊查詢的  本身就唯一 不存在多個

  

如果列型別是字串,一定要在條件中將資料使用引號,否則用不到索引

  

 

  1. 索引無法儲存null值
  2. 前導模糊查詢不能利用索引(like '%XX'或者like '%XX%')
  3. 索引失效的幾種情況

         1.如果條件中有or,即使其中有條件帶索引也不會使用(這也是為什麼儘量少用or的原因)要想使用or,又想讓索引生效,只能將or條件中的每個列都加上索引

         2.對於多列索引,不是使用的第一部分,則不會使用索引

         3.like查詢以%開頭

         4.如果列型別是字串,那一定要在條件中將資料使用引號引用起來,否則不使用索引

         5.如果mysql估計使用全表掃描要比使用索引快,則不使用索引

 

 

 

聯合索引為什麼需要遵循左字首原則?

  建立表:

CREATE TABLE `user_details` (
  `id` int(11) ,
  `user_name` varchar(50) ,
  `user_phone` varchar(11) DEFAULT NULL,
  PRIMARY KEY (id,user_name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 主鍵是id   user_name   

 

  

insert into user_details values(1,'a1','12312312');

insert into user_details values(1,'a2','12312123');

可以插入成功! 聯合主鍵索引  id+user_name保證唯一就OK了!  多個

 

插入如下資料:

  

insert into user_details values(1,'a1','12312123');

insert into user_details values(1,'a2','12312123');


insert into user_details values(2,'a1','12312123');

insert into user_details values(2,'a2','12312123');


insert into user_details values(3,'a1','12312123');

insert into user_details values(3,'a2','12312123');

 

如果只有一個條件 user_name

 

 

 聯合主鍵索引中: 左字首指的就是第一個索引 id  

 聯合主鍵索引中,必須要加上左字首,才會生效?

  

 葉子節點分析 連結串列, 

 [1+a1] ---> [1+a2] ---->  [2+a1]---> [2+a2]--->[3+a1]--->[3+a2]

  

 select * from user_deatils where id = 1 and user_name = 'a1'

 通過字首就可以查詢到葉子,知道有個範圍了  “範圍”是個亮點!!!

 如果不帶第一個索引 查詢時候 會因為不知道第一個索引是什麼,只有第二個,而進行全表查詢

 因為索引底層採用B+樹葉子節點順序排列,必須通過左字首索引才能定位到具體的節點範圍。

  

聯合主鍵索引:

 

 

 分表分庫能夠提高資料查詢效率?

  

分表分庫為什麼提高查詢的效率?因為會將一張表的資料拆分成多個n張表進行存放,讓後在使用第三方中介軟體(MyCat或者Sharding-JDBC)並行同時查詢,讓後在交給第三方中間進行組合返回給客戶端。

 

 

同時操作,就跟多執行緒一樣。 

分表分庫為什麼提高查詢的效率?因為會將一張表的資料拆分成多個n張表進行存放,讓後在使用第三方中介軟體(MyCat或者Sharding-JDBC)並行同時查詢,讓後在交給第三方中間進行組合返回給客戶端。

 

 

不適合建索引的欄位


 

索引的建立必須慎重,對每個索引的必要性都應該經過仔細分析,要有建立的依據。 
因為太多的索引與不充分、不正確的索引對效能都毫無益處:在表上建立的每個索引都會增加儲存開銷,索引對於插入、刪除、更新操作也會增加處理上的開銷。 另外,過多的複合索引,在有單欄位索引的情況下,一般都是沒有存在價值的;相反,還會降低資料增加刪除時的效能,特別是對頻繁更新的表來說,負面影響更大。 
總的來說,小型表肯定不建索引, 
或者資料庫記錄在億條資料級以上,還是建議使用非關係型資料庫。 
還有些特殊欄位的資料庫,比如BLOB,CLOB欄位肯定也不適合建索引。 

 

從以下幾個方面分析:

1. 建立索引

也不是什麼情況都非得建索引不可,比如性別可能就只有兩個值,建索引不僅沒什麼優勢,還會影響到更新速度,這被稱為過度索引。

2. 複合索引

select * from users where area=’beijing’ and age=22; 在area和age上分別建立單個索引的話,由於mysql查詢每次只能使用一個索引,這樣已經相對不做索引時全表掃描提高了效率。但是如果在area、age兩列上建立複合索引的話將帶來更高的效率。如果我們建立了(area, age, salary)的複合索引,那麼其實相當於建立了(area,age,salary)、(area,age)、(area)三個索引,這被稱為最佳左字首 特性。因此我們在建立複合索引時應該將最常用作限制條件的列放在最左邊,依次遞減。

注1:在mysql中執行查詢時,只能使用一個索引,如果我們在lname,fname,age上分別建索引,執行查詢時,只能使用一個索引,mysql會選擇一個最嚴格(獲得結果集記錄數最少)的索引。

注2:在建立多列索引時,要根據業務需求,where子句中使用最頻繁的一列放在最左邊。

MySQL 最左字首匹配原則(即建立聯合索引的使用)

1、在mysql建立聯合索引時會遵循最左字首匹配的原則,即最左優先,在檢索資料時從聯合索引的最左邊開始匹配,示例:
對列col1、列col2和列col3建一個聯合索引

KEY index_col1_col2_col3 on test(col1,col2,col3);

聯合索引 index_col1_col2_col3 實際建立了(col1)、(col1,col2)、(col,col2,col3)三個索引。

SELECT * FROM table WHERE col1="1" AND clo2="2" AND clo4="4"

上面這個查詢語句執行時會依照最左字首匹配原則,檢索時會使用索引(col1,col2)進行資料匹配。索引的欄位可以是任意順序的。

使用聯合索引的好處

  • 減少開銷。每多一個索引,都會增加寫操作的開銷和磁碟空間的開銷。對於大量資料的表,使用聯合索引會大大的減少開銷!
  • 效率高。索引列越多,通過索引篩選出的資料越少。

3.索引不會包含有NULL值的列

只要列中包含有NULL值都將不會被包含在索引中,複合索引中只要有一列含有NULL值,那麼這一列對於此複合索引就是無效的。所以我們在資料庫設計時不要讓欄位的預設值為NULL。

4.使用短索引

對串列進行索引,如果可能應該指定一個字首長度。例如,如果有一個CHAR(255)的 列,如果在前10 個或20 個字元內,多數值是惟一的,那麼就不要對整個列進行索引。短索引不僅可以提高查詢速度而且可以節省磁碟空間和I/O操作。

5.排序的索引問題

mysql查詢只使用一個索引,因此如果where子句中已經使用了索引的話,那麼order by中的列是不會使用索引的。因此資料庫預設排序可以符合要求的情況下不要使用排序操作;儘量不要包含多個列的排序,如果需要最好給這些列建立複合索引。

6.like語句操作

一般情況下不鼓勵使用like操作,如果非使用不可,如何使用也是一個問題。like “%a%” 不會使用索引而like “aaa%”可以使用索引。

7.不要在列上進行運算

select * from users where YEAR(adddate)

8.不使用NOT IN和操作

NOT IN和操作都不會使用索引將進行全表掃描。NOT IN可以NOT EXISTS代替,id3則可使用id>3 or id

 

 

索引的一些分類:

1.普通索引index :加速查詢
2.唯一索引
    主鍵索引:primary key :加速查詢+約束(不為空且唯一)
    唯一索引:unique:加速查詢+約束 (唯一)
3.聯合索引
    -primary key(id,name):聯合主鍵索引
    -unique(id,name):聯合唯一索引
    -index(id,name):聯合普通索引
4.全文索引fulltext :用於搜尋很長一篇文章的時候,效果最好。
5.空間索引spatial :瞭解就好,幾乎不用

 

談一談InnoDb索引的使用,一直以來專案開發用的都是InnoD引擎,而innodb使用的是b+tree進行儲存,資料存放在子節點上

多列索引如何決定順序

  • 選擇性高的放在最左邊
  • 把長度小的列放在左側(單頁可以容納的資料更多,減少io)
  • 使用最頻繁的放在左側

  組合索引的生效原則是  從前往後依次使用生效,如果中間某個索引沒有使用,那麼斷點前面的索引部分起作用,斷點後面的索引沒有起作用

 

比如

where a=3 and b=45 and c=5 .... 這種三個索引順序使用中間沒有斷點,全部發揮作用;
where a=3 and c=5... 這種情況下b就是斷點,a發揮了效果,c沒有效果
where b=3 and c=4... 這種情況下a就是斷點,在a後面的索引都沒有發揮作用,這種寫法聯合索引沒有發揮任何效果;
where b=45 and a=3 and c=5 .... 這個跟第一個一樣,全部發揮作用,abc只要用上了就行,跟寫的順序無關

(a,b,c) 三個列上加了聯合索引(是聯合索引 不是在每個列上單獨加索引)

注:,  (a,b,c)多列索引和 (a,c,b)是不一樣的

複製程式碼
(0)    select * from mytable where a=3 and b=5 and c=4;
abc三個索引都在where條件裡面用到了,而且都發揮了作用
(1)    select * from mytable where  c=4 and b=6 and a=3;
這條語句列出來只想說明 mysql沒有那麼笨,where裡面的條件順序在查詢之前會被mysql自動優化,效果跟上一句一樣
(2)    select * from mytable where a=3 and c=7;
a用到索引,b沒有用,所以c是沒有用到索引效果的
(3)    select * from mytable where a=3 and b>7 and c=3;
a用到了,b也用到了,c沒有用到,這個地方b是範圍值,也算斷點,只不過自身用到了索引
(4)    select * from mytable where b=3 and c=4;
因為a索引沒有使用,所以這裡 bc都沒有用上索引效果
(5)    select * from mytable where a>4 and b=7 and c=9;
a用到了  b沒有使用,c沒有使用
(6)    select * from mytable where a=3 order by b;
a用到了索引,b在結果排序中也用到了索引的效果,前面說了,a下面任意一段的b是排好序的
(7)    select * from mytable where a=3 order by c;
a用到了索引,但是這個地方c沒有發揮排序效果,因為中間斷點了,使用 explain 可以看到 filesort
(8)    select * from mytable where b=3 order by a;
b沒有用到索引,排序中a也沒有發揮索引效果

 

索引是一種資料結構:

 

 索引採用的B+樹,為何用B+樹呢?

 

引入二叉查詢樹:這個約束性很差 可能會出現連結串列的樣子!

 

   

 

 

平衡二分查詢樹:

兩種   種類1: AVL樹 插入時候會左選裝,檢查平衡因子,高度差,不滿足時候,做一些操作,讓其平衡。    

 

 

(上圖中資料區要麼存地址,要麼存資料。 注意標註的是磁碟塊)

 

 

種類2:

紅黑樹 (略)

 

二叉樹缺陷:

 1. 搜尋效率問題:樹的深度決定了搜尋時候IO的次數。

 2. 內容數量問題: 

   每一個磁碟塊(節點/頁)儲存的關鍵字數量太少了。

  沒有利用好作業系統和磁碟的資料互動特性,作業系統和磁碟進行資料互動.也沒有利用好磁碟IO預讀能力(空間區域性性原理)

     備註:交換的單位是頁 4k (ssd 4k對齊)做一次IO 載入4k 浪費資源!

  

多路平衡查詢樹:

  

路: 叉 分叉 關鍵字的個數 等於 路-1 比如:小於17 大於25 介於之間

 

 

B樹的變種,MySQL的B+樹:

 

 

 

B+樹和B-樹的區別

 B+樹的關鍵字搜尋採用閉合區間

 B+樹的非葉子節點不儲存資料相關資訊,只儲存關鍵字和子節點引用。

 B+樹關鍵字對應的資料儲存在葉子節點中

 B+樹葉子節點是順序排列的,並且相鄰節點具有順序引用的關係。

 

    MySQL引擎: 一個庫中不同的表可以用不同的儲存引擎   MyISAM:

 

 

 

 

 

 

 

InnoDB:

 

 

 

 

 

 

 InnoDB VS MyISAM:

 

 

 

索引的幾大原則:   1.離散型越高選擇性越好  對索引的關鍵字進行(計算)對比,一定是從左往右依次進行,且不可以跳過。

 

2. 聯合索引

  單列索引: 節點中關鍵字【name】

  聯合索引: 節點中關鍵字 【name, sex, mobile】

 注:  單列索引是特殊的聯合索引

 

聯合索引列選擇原則:

  1.經常用的列優先(最左匹配原則)

  2.離散度高的優先(離散度高原則)

  3.寬度小的列優先(最少空間原則)

 

 

最左匹配原則:

比如經常用到:

SELECT * FROM `user` WHERE `name` = "";
SELECT * FROM `user` WHERE `name`= "" AND mobile = ""

則應該這樣建立索引:

 

 

 

 create index idx_name_mobile on user (name, mobile)

 

覆蓋索引:

  • 解釋一: 就是select的資料列只用從索引中就能夠取得,不必從資料表中讀取,換句話說查詢列要被所使用的索引覆蓋。
  • 解釋二: 索引是高效找到行的一個方法,當能通過檢索索引就可以讀取想要的資料,那就不需要再到資料表中讀取行了。如果一個索引包含了(或覆蓋了)滿足查詢語句中欄位與條件的資料就叫做覆蓋索引。
  • 解釋三:是非聚集組合索引的一種形式,它包括在查詢裡的Select、Join和Where子句用到的所有列(即建立索引的欄位正好是覆蓋查詢語句[select子句]與查詢條件[Where子句]中所涉及的欄位,也即,索引包含了查詢正在查詢的所有資料)。

 

 

即: 如果查詢的列,通過索引項的資訊可以直接返回,則改索引稱為該sql的覆蓋索引。

 

 

 轉載自  https://www.cnblogs.com/toov5/p/10340349.html