欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

mysql聚集索引、輔助索引、覆蓋索引、聯(lián)合索引的使用

 更新時(shí)間:2022年02月11日 10:48:43   作者:BingoOnline  
本文主要介紹了mysql聚集索引、輔助索引、覆蓋索引、聯(lián)合索引的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

《MySQL技術(shù)內(nèi)幕 InnoDB存儲(chǔ)引擎》學(xué)習(xí)筆記

聚集索引(Clustered Index)

聚集索引就是按照每張表的主鍵構(gòu)造一棵B+樹(shù),同時(shí)葉子節(jié)點(diǎn)中存放的即為整張表的行記錄數(shù)據(jù)。

舉個(gè)例子,直觀感受下聚集索引。

創(chuàng)建表t,并以人為的方式讓每個(gè)頁(yè)只能存放兩個(gè)行記錄(不清楚怎么人為控制每頁(yè)只存放兩個(gè)行記錄):

這里寫圖片描述

最后《MySQL技術(shù)內(nèi)幕》的作者通過(guò)分析工具得到這棵聚集索引樹(shù)的大致構(gòu)造如下:

這里寫圖片描述

聚集索引的葉子節(jié)點(diǎn)稱為數(shù)據(jù)頁(yè),每個(gè)數(shù)據(jù)頁(yè)通過(guò)一個(gè)雙向鏈表來(lái)進(jìn)行鏈接,而且數(shù)據(jù)頁(yè)按照主鍵的順序進(jìn)行排列。

如圖所示,每個(gè)數(shù)據(jù)頁(yè)上存放的是完整的行記錄,而在非數(shù)據(jù)頁(yè)的索引頁(yè)中,存放的僅僅是鍵值及指向數(shù)據(jù)頁(yè)的偏移量,而不是一個(gè)完整的行記錄。

如果定義了主鍵,InnoDB會(huì)自動(dòng)使用主鍵來(lái)創(chuàng)建聚集索引。如果沒(méi)有定義主鍵,InnoDB會(huì)選擇一個(gè)唯一的非空索引代替主鍵。如果沒(méi)有唯一的非空索引,InnoDB會(huì)隱式定義一個(gè)主鍵來(lái)作為聚集索引。

輔助索引(Secondary Index)

輔助索引,也叫非聚集索引。和聚集索引相比,葉子節(jié)點(diǎn)中并不包含行記錄的全部數(shù)據(jù)。葉子節(jié)點(diǎn)除了包含鍵值以外,每個(gè)葉子節(jié)點(diǎn)的索引行還包含了一個(gè)書簽(bookmark),該書簽用來(lái)告訴InnoDB哪里可以找到與索引相對(duì)應(yīng)的行數(shù)據(jù)。

還是以《MySQL技術(shù)內(nèi)幕》中的例子,來(lái)直觀感受下輔助索引的模樣。

還是以上面的表t為例,在列c上創(chuàng)建非聚集索引:

這里寫圖片描述

然后作者通過(guò)分析工作得到輔助索引和聚集索引的關(guān)系圖:

這里寫圖片描述

可以看到輔助索引idx_c的葉子節(jié)點(diǎn)中包含了列c的值和主鍵的值。

以Key為7fffffff為例,7是0111,0代表負(fù)數(shù),真實(shí)的值應(yīng)該取反加1,是-1,這是列c的值。Pointer是80000001,8是1000,1代表正數(shù),所以80000001代表1,是主鍵的值。

覆蓋索引(Covering index)

InnoDB存儲(chǔ)引擎支持覆蓋索引,即從輔助索引中就可以得到查詢的記錄,而不需要查詢聚集索引中的記錄。

使用覆蓋索引有啥好處?

  • 可以減少大量的IO操作

上圖中我們知道,如果要查詢輔助索引中不含有的字段,得先遍歷輔助索引,再遍歷聚集索引,而如果要查詢的字段值在輔助索引上就有,就不用再查聚集索引了,這顯然會(huì)減少IO操作。

比如上圖中,以下sql可以直接使用輔助索引,

select a from where c = -2;
  • 有助于統(tǒng)計(jì)

假設(shè)存在如下表:

  CREATE TABLE `student` (
  `id` bigint(20) NOT NULL,
  `name` varchar(255) NOT NULL,
  `age` varchar(255) NOT NULL,
  `school` varchar(255) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`),
  KEY `idx_school_age` (`school`,`age`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

如果在該表上執(zhí)行:

select count(*) from student

優(yōu)化器會(huì)怎么處理?

遍歷聚集索引和輔助索引都可以統(tǒng)計(jì)出結(jié)果,但輔助索引要遠(yuǎn)小于聚集索引,所以優(yōu)化器會(huì)選擇輔助索引來(lái)統(tǒng)計(jì)。執(zhí)行explain命令:

這里寫圖片描述

key和Extra顯示使用了idx_name這個(gè)輔助索引。

還有,假設(shè)執(zhí)行以下sql:

select * from student where age > 10 and age < 15

因?yàn)槁?lián)合索引idx_school_age的字段順序是先school再age,按照age做條件查詢,通常不走索引:

這里寫圖片描述

但是,如果保持條件不變,查詢所有字段改為查詢條目數(shù):

select count(*) from student where age > 10 and age < 15

優(yōu)化器會(huì)選擇這個(gè)聯(lián)合索引:

這里寫圖片描述

聯(lián)合索引

聯(lián)合索引是指對(duì)表上的多個(gè)列進(jìn)行索引。

以下為創(chuàng)建聯(lián)合索引idx_a_b的示例:

這里寫圖片描述

聯(lián)合索引的內(nèi)部結(jié)構(gòu):

這里寫圖片描述

聯(lián)合索引也是一棵B+樹(shù),其鍵值數(shù)量大于等于2。鍵值都是排序的,通過(guò)葉子節(jié)點(diǎn)可以邏輯上順序的讀出所有數(shù)據(jù)。數(shù)據(jù)(1,1)(1,2)(2,1)(2,4)(3,1)(3,2)是按照(a,b)先比較a再比較b的順序排列。

基于上面的結(jié)構(gòu),對(duì)于以下查詢顯然是可以使用(a,b)這個(gè)聯(lián)合索引的:

select * from table where a=xxx and b=xxx ;

select * from table where a=xxx;

但是對(duì)于下面的sql是不能使用這個(gè)聯(lián)合索引的,因?yàn)槿~子節(jié)點(diǎn)的b值,1,2,1,4,1,2顯然不是排序的。

select * from table where b=xxx

聯(lián)合索引的第二個(gè)好處是對(duì)第二個(gè)鍵值已經(jīng)做了排序。舉個(gè)例子:

create table buy_log(
    userid int not null,
    buy_date DATE
)ENGINE=InnoDB;

insert into buy_log values(1, '2009-01-01');
insert into buy_log values(2, '2009-02-01');

alter table buy_log add key(userid);
alter table buy_log add key(userid, buy_date);

當(dāng)執(zhí)行

select * from buy_log where user_id = 2;

時(shí),優(yōu)化器會(huì)選擇key(userid);但是當(dāng)執(zhí)行以下sql:

select * from buy_log where user_id = 2 order by buy_date desc;

時(shí),優(yōu)化器會(huì)選擇key(userid, buy_date),因?yàn)閎uy_date是在userid排序的基礎(chǔ)上做的排序。

如果把key(userid,buy_date)刪除掉,再執(zhí)行:

select * from buy_log where user_id = 2 order by buy_date desc;

優(yōu)化器會(huì)選擇key(userid),但是對(duì)查詢出來(lái)的結(jié)果會(huì)進(jìn)行一次filesort,即按照buy_date重新排下序。所以聯(lián)合索引的好處在于可以避免filesort排序。

到此這篇關(guān)于mysql聚集索引、輔助索引、覆蓋索引、聯(lián)合索引的使用的文章就介紹到這了,更多相關(guān)聚集索引、輔助索引、覆蓋索引、聯(lián)合索引內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • mysql中日期的加減 date_add()、date_sub() 函數(shù)及用法小結(jié)

    mysql中日期的加減 date_add()、date_sub() 函數(shù)及用法小結(jié)

    在Mysql中,date_add與date_sub分別是指對(duì)于日期的一個(gè)加減操作,date_add是指從日期中加上指定的時(shí)間間隔,date_sub是指從日期中減去指定的時(shí)間間隔,本文通過(guò)實(shí)例講解mysql中日期的加減 date_add()、date_sub() 函數(shù)及用法小結(jié),感興趣的朋友一起看看吧
    2023-11-11
  • ORM模型框架操作mysql數(shù)據(jù)庫(kù)的方法

    ORM模型框架操作mysql數(shù)據(jù)庫(kù)的方法

    ORM 全稱是(Object Relational Mapping)表示對(duì)象關(guān)系映射; 通俗理解可以理解為編程語(yǔ)言的虛擬數(shù)據(jù)庫(kù);這篇文章主要介紹了ORM模型框架操作mysql數(shù)據(jù)庫(kù)的方法,需要的朋友可以參考下
    2021-07-07
  • mysql 報(bào)錯(cuò) incompatible with sql_mode=only_full_group_by解決

    mysql 報(bào)錯(cuò) incompatible with sql_mode=only

    這篇文章主要為大家介紹了mysql 報(bào)錯(cuò) incompatible with sql_mode=only_full_group_by解決方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • MySQL聚合查詢與聯(lián)合查詢操作實(shí)例

    MySQL聚合查詢與聯(lián)合查詢操作實(shí)例

    這篇文章主要給大家介紹了關(guān)于MySQL聚合查詢與聯(lián)合查詢操作的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用MySQL具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-02-02
  • mysql中union和union?all的使用及注意事項(xiàng)

    mysql中union和union?all的使用及注意事項(xiàng)

    這篇文章主要給大家介紹了關(guān)于mysql中union和union?all的使用及注意事項(xiàng)的相關(guān)資料,需要的朋友可以參考下
    2022-08-08
  • MySQL表列數(shù)和行大小限制示例詳解

    MySQL表列數(shù)和行大小限制示例詳解

    行是表中存儲(chǔ)數(shù)據(jù)的行,也稱為記錄,MySQL的行上限主要受限于兩個(gè)因素,表的大小和操作系統(tǒng)的限制,這篇文章主要給大家介紹了關(guān)于MySQL表列數(shù)和行大小限制的相關(guān)資料,需要的朋友可以參考下
    2024-04-04
  • MySQL大庫(kù)搭建主從的一種思路分享

    MySQL大庫(kù)搭建主從的一種思路分享

    這篇文章主要介紹了MySQL大庫(kù)搭建主從的一種思路分享,幫助大家更好的理解和學(xué)習(xí)使用MySQL數(shù)據(jù)庫(kù),感興趣的朋友可以了解下
    2021-03-03
  • MySQL保證數(shù)據(jù)不丟失的方案詳解

    MySQL保證數(shù)據(jù)不丟失的方案詳解

    MySQL作為一個(gè)存儲(chǔ)數(shù)據(jù)的產(chǎn)品,怎么確保數(shù)據(jù)的持久性和不丟失才是最重要的,感興趣的可以跟隨本文一探究竟,文中通過(guò)圖文結(jié)合給大家講解的非常詳細(xì),需要的朋友快來(lái)跟著小編一起來(lái)學(xué)習(xí)吧
    2023-12-12
  • mysql自定義函數(shù)原理與用法實(shí)例分析

    mysql自定義函數(shù)原理與用法實(shí)例分析

    這篇文章主要介紹了mysql自定義函數(shù),結(jié)合實(shí)例形式分析了mysql自定義函數(shù)基本功能、原理、用法及操作注意事項(xiàng),需要的朋友可以參考下
    2020-04-04
  • MySQL學(xué)習(xí)記錄之KEY分區(qū)引發(fā)的血案

    MySQL學(xué)習(xí)記錄之KEY分區(qū)引發(fā)的血案

    這篇文章主要給大家介紹了關(guān)于MySQL學(xué)習(xí)記錄之KEY分區(qū)引發(fā)的血案的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11

最新評(píng)論