索引

零、什么是索引?

  1. 索引是幫助MySQL 高效獲取數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)
  2. 索引存儲(chǔ)在文件系統(tǒng)中
  3. 索引的文件存儲(chǔ)形式與存儲(chǔ)引擎有關(guān)
  4. 索引的文件結(jié)構(gòu)
    4.1 hash
    4.2 二叉樹(shù)
    4.3 B樹(shù)
    4.4 B+ 樹(shù)

一、索引的常見(jiàn)模型

  1. hash:鍵值對(duì)存儲(chǔ)數(shù)據(jù)結(jié)構(gòu)(實(shí)現(xiàn)方式:數(shù)組+鏈表),值放在數(shù)組中,用hash 函數(shù)把key 換算成一個(gè)確定的位置,然后把value 放在數(shù)組的這個(gè)位置。
    哈希碰撞:不同的key 值通過(guò)hash 函數(shù)算出的值相同,處理方式就是在數(shù)組的該位置拉出一個(gè)鏈表。
    hash 存儲(chǔ)只適合等值查詢,不適合范圍查詢,實(shí)際工作中范圍查詢的情況更多,所以hash 存儲(chǔ)更適合一些NoSQL 引擎。
    hash 索引并不是按照索引順序存儲(chǔ)的,無(wú)法排序。當(dāng)存在hash 沖突,維護(hù)操作的成本也會(huì)增加。

  2. BST樹(shù)(二叉搜索樹(shù)):二叉搜索樹(shù)的特點(diǎn)是:每個(gè)節(jié)點(diǎn)的左兒子小于父節(jié)點(diǎn),父節(jié)點(diǎn)又小于右兒子。二叉樹(shù)的查詢效率挺高的(時(shí)間復(fù)雜度是O(log2(n))),但是有可能出現(xiàn)一條鏈?zhǔn)浇Y(jié)構(gòu)。


  3. AVL 樹(shù)(自平衡二叉搜索樹(shù)):AVL樹(shù)定義是任意節(jié)點(diǎn)的兩個(gè)子節(jié)點(diǎn)高度差不超過(guò)1。AVL樹(shù)本質(zhì)上是帶了平衡功能的二叉搜索樹(shù)。



    解決上圖的辦法:通過(guò) 左旋維護(hù)去維護(hù)平衡。



    也就是說(shuō)AVL樹(shù)維護(hù)平衡的成本很高,每次增加或刪除一個(gè)節(jié)點(diǎn)需要多次左旋或者右旋去維護(hù)樹(shù)的平衡。如果節(jié)點(diǎn)多的情況下AVL 樹(shù)的高度還是會(huì)比較高且查詢不穩(wěn)定(看運(yùn)氣)。
    AVL 樹(shù)節(jié)點(diǎn)存儲(chǔ)的數(shù)據(jù)內(nèi)容太少,在二叉樹(shù)每個(gè)節(jié)點(diǎn)的結(jié)構(gòu)只能保存一個(gè)關(guān)鍵字,一個(gè)數(shù)據(jù)區(qū),兩個(gè)子節(jié)點(diǎn)的引用,并不能填滿4k的內(nèi)容,即每次IO操作系統(tǒng)會(huì)將4k 數(shù)據(jù)加載到內(nèi)存。
  4. B 樹(shù):有序數(shù)組+ 平衡二叉樹(shù);B樹(shù)每個(gè)節(jié)點(diǎn)都存儲(chǔ)了key和data,B樹(shù)提高了磁盤(pán)IO性能的同時(shí)并沒(méi)有解決元素遍歷的效率低下的問(wèn)題。

  5. B+ 樹(shù):有序數(shù)組鏈表+平衡多叉樹(shù);B+ 樹(shù)的data 存儲(chǔ)在葉子節(jié)點(diǎn)上,B+樹(shù)能夠很好地配合磁盤(pán)的讀寫(xiě)特性,減少單次查詢的磁盤(pán)訪問(wèn)次數(shù)。每一個(gè)索引在InnoDB里面對(duì)應(yīng)一棵B+樹(shù),主鍵索引的葉子節(jié)點(diǎn)存的是整行數(shù)據(jù),在InnoDB里,主鍵索引也被稱(chēng)為聚簇索引。非主鍵索引的葉子節(jié)點(diǎn)內(nèi)容是主鍵的值,在InnoDB里,非主鍵索引也被稱(chēng)為二級(jí)索引。

二、MySQL索引類(lèi)型

  1. Normal 普通索引

  2. Unique 唯一索引:表示唯一的,不允許重復(fù)的索引。添加唯一性索引的數(shù)據(jù)列可以為空,但是只要存在數(shù)據(jù)值,就必須是唯一的。創(chuàng)建唯一索引的目的不是為了提高訪問(wèn)速度,而只是為了避免數(shù)據(jù)出現(xiàn)重復(fù)。

  3. Full Text 全文索引:MySQL5.6.24上InnoDB引擎也加入了全文索引。全文索引的運(yùn)用見(jiàn)《https://blog.csdn.net/yygg329405/article/details/97110984

  4. SPATIAL 空間索引:空間索引是對(duì)空間數(shù)據(jù)類(lèi)型的字段建立的索引,MYSQL中的空間數(shù)據(jù)類(lèi)型有4種。

  5. btree索引和hash索引的區(qū)別:BTREE(B樹(shù)(可以是多叉樹(shù))) {主流使用};HASH(key,value) 這種方式對(duì)范圍查詢支持得不是很好《https://blog.csdn.net/guo_qiangqiang/article/details/88794971

三、索引的技術(shù)名稱(chēng)

  1. 回表:回到主鍵索引樹(shù)搜索的過(guò)程,我們稱(chēng)為回表。
  2. 索引覆蓋:不需要回表操作,如通過(guò)二級(jí)索引查詢主鍵,二級(jí)索引的葉子節(jié)點(diǎn)已經(jīng)存儲(chǔ)了主鍵值,所以不需要回表,減少樹(shù)的搜索次數(shù)。
  3. 最左匹配:創(chuàng)建一個(gè)組合索引,最左前綴可以是聯(lián)合索引的最左N個(gè)字段,也可以是字符串索引的最左M個(gè)字符。
聯(lián)合索引為key idx_a_b_c(a,b,c)
是否使用索引
where a = x and b = x and c = x   是
where a = x and b = x    是,部分索引
where a = x    是,部分索引
where b = x    否,不包含最左列a
where b = x and c = x    否,不包含最左列a

MySQL中,有兩種方式生成有序結(jié)果集:
1. 通過(guò)有序索引順序掃描直接返回有序數(shù)據(jù)
2. Filesort排序,對(duì)返回的數(shù)據(jù)進(jìn)行排序
可以用export 命令查看Extra列是否有Using filesort進(jìn)行了額外排序

假如說(shuō)有如下聯(lián)合索引,key idx_a_b_c(a,b,c)
order by 能使用索引排序
order by a
order by a,b
order by a,b,c
order by a desc, b desc, c desc
where a = const order by b,c
where a = const and b = const order by c
where a = const and b > const order by b,c

order by 不能使用索引進(jìn)行排序
rder by b
order by c
order by b, c
order by a asc, b desc, c desc //排序不一致
where g = const order by b,c //丟失a索引
where a = const order by c //丟失b索引
where a = const order by a,d //d不是索引的一部分
where a in (...) order by b,c //范圍查詢

建一個(gè)聯(lián)合索引(col1,col2,col3),實(shí)際相當(dāng)于建了(col1),(col1,col2),(col1,col2,col3)三個(gè)索引。
每多一個(gè)索引,都會(huì)增加寫(xiě)操作的開(kāi)銷(xiāo)和磁盤(pán)空間的開(kāi)銷(xiāo)。對(duì)于大量數(shù)據(jù)的表,使用聯(lián)合索引會(huì)大大增加開(kāi)銷(xiāo)!
  1. 索引下推:對(duì)于不符合最左前綴的部分在索引遍歷過(guò)程中,對(duì)索引中包含的字段先做判斷,直接過(guò)濾掉不滿足條件的記錄,減少回表次數(shù)。
建一個(gè)聯(lián)合索引(name, age)
SQL語(yǔ)句是這么寫(xiě):
mysql> select * from tuser where name like '張%' and age=10 and ismale=1;
根據(jù)最左前綴索引規(guī)則,搜索索引樹(shù)的時(shí)候,只能用 “張”。MySQL 5.6之前只能從匹配出的數(shù)據(jù)一個(gè)一個(gè)的回表再對(duì)比字段值。
MySQL 5.6 引入的索引下推優(yōu)化, 可以在索引遍歷過(guò)程中,對(duì)索引中包含的字段先做判斷,直接過(guò)濾掉不滿足條件的記錄,減少回表次數(shù)。
InnoDB的索引組織結(jié)構(gòu)

四、索引的優(yōu)化

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者。

相關(guān)閱讀更多精彩內(nèi)容

  • 索引 數(shù)據(jù)庫(kù)中的查詢操作非常普遍,索引就是提升查找速度的一種手段 索引的類(lèi)型 從數(shù)據(jù)結(jié)構(gòu)角度分 1.B+索引:傳統(tǒng)...
    一凡呀閱讀 3,206評(píng)論 0 8
  • 1.索引的本質(zhì)? 1)定義:數(shù)據(jù)庫(kù)索引,是數(shù)據(jù)庫(kù)管理系統(tǒng)(DBMS)中一個(gè)排序的數(shù)據(jù)結(jié)構(gòu),以協(xié)助快速查詢、更新數(shù)據(jù)...
    三個(gè)石頭_260a閱讀 625評(píng)論 0 0
  • 索引是一種數(shù)據(jù)結(jié)構(gòu),用于幫助我們?cè)诖罅繑?shù)據(jù)中快速定位到我們想要查找的數(shù)據(jù)。 索引最形象的比喻就是圖書(shū)的目錄了。注意...
    ___n閱讀 527評(píng)論 0 6
  • 要了解數(shù)據(jù)庫(kù)索引的底層原理,我們就得先了解一種叫樹(shù)的數(shù)據(jù)結(jié)構(gòu),而樹(shù)中很經(jīng)典的一種數(shù)據(jù)結(jié)構(gòu)就是二叉樹(shù)!所以下面我們就...
    萍_467a閱讀 967評(píng)論 0 1
  • 前幾天某小跟我說(shuō),嘗試下在說(shuō)話的時(shí)候不要加上“我以為”這3個(gè)字,如果你成功了,那你就成熟很多了。 其實(shí)仔細(xì)想想,“...
    小蟲(chóng)子WonderDT閱讀 584評(píng)論 3 1

友情鏈接更多精彩內(nèi)容