日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

数据库索引类型介绍及其优缺点、区别、适用场景

發(fā)布時間:2024/8/1 数据库 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据库索引类型介绍及其优缺点、区别、适用场景 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

索引

索引分為主鍵索引、唯一索引、普通索引、聚集索引、全文索引幾種,而索引其實(shí)就是在無序的數(shù)據(jù)中建立索引,每次查詢可以根據(jù)索引迅速查到我們想要的數(shù)據(jù)(就像字典的目錄a-z一樣)

  • 優(yōu)點(diǎn)

    • 提高數(shù)據(jù)查找速度
    • 提高group by、order by分組與排序的時間
  • 缺點(diǎn)

    • 每增加數(shù)據(jù)都需要更新索引,隨者數(shù)據(jù)量增大,索引維護(hù)成本會增加
    • 占用一定的存儲空間,.myi后綴的文件存儲的就是索引文件。

索引類型

主鍵索引

數(shù)據(jù)列不允許重復(fù),不允許為NULL,可以被引用為外鍵,一個表只能有一個主鍵索引

唯一索引

數(shù)據(jù)列不允許重復(fù),允許為NULL值,不可以被引用為外鍵,一個表允許多個列創(chuàng)建唯一索引

普通索引

基本的索引類型,沒有唯一性限制,允許為NULL值,不可以被引用為外鍵,一個表可以有多個普通索引

主鍵索引、唯一索引、普通索引區(qū)別:

索引類型數(shù)據(jù)是否允許重復(fù)是否允許NULL是否可以當(dāng)作外鍵索引個數(shù)限制
主鍵索引僅有一個
唯一索引允許多個
普通索引允許多個

表中可以看出約束是從高到低,對比表種內(nèi)容然后依據(jù)不同場景進(jìn)行使用

聚集索引(聚簇索引)

在聚集索引中,表中數(shù)據(jù)行的物理位置與邏輯值(索引和數(shù)據(jù)為同一個文件)的順序相同,一個表中只能包含一個聚集索引,因為物理順序只能有一個。聚集索引通常提供更快的數(shù)據(jù)訪問速度。
其中 InnoDB采用的就是聚簇索引,數(shù)據(jù)和索引文件為一個idb文件,表數(shù)據(jù)文件本身就是主索引,相鄰的索引臨近存儲。 葉節(jié)點(diǎn)data域保存了完整的數(shù)據(jù)記錄(數(shù)據(jù)[除主鍵id外其他列data]+主索引[索引key:表主鍵id])。 葉子節(jié)點(diǎn)直接存儲數(shù)據(jù)記錄,以主鍵id為key,葉子節(jié)點(diǎn)中直接存儲數(shù)據(jù)記錄。(底層存儲結(jié)構(gòu): frm -表定義、 ibd: innoDB數(shù)據(jù)&索引文件)

(1)如果表定義了主鍵,則PK就是聚集索引;
(2)如果表沒有定義主鍵,則第一個非空唯一索引(not NULL unique)列是聚集索引;
(3)否則,InnoDB會創(chuàng)建一個隱藏的row-id作為聚集索引;

非聚簇索引

索引和數(shù)據(jù)分開的索引。
其中MyISAM底層采用的就是非聚簇索引,使用myi索引文件和myd數(shù)據(jù)文件分離,索引文件僅保存數(shù)據(jù)記錄的指針地址。葉子節(jié)點(diǎn)data域存儲指向數(shù)據(jù)記錄的指針地址。(底層存儲結(jié)構(gòu): frm -表定義、 myi -myisam索引、 myd-myisam數(shù)據(jù))

覆蓋索引

所謂覆蓋索引就是指索引中包含了查詢中的所有字段,這種情況下就不需要再進(jìn)行回表查詢了
MySQL 中只能使用 B-Tree 索引做覆蓋索引,因為哈希索引等都不存儲索引的列的值,覆蓋索引對于 MyISAM 和 InnoDB 都非常有效,可以減少系統(tǒng)調(diào)用和數(shù)據(jù)拷貝等時間

組合索引

使用多個列來組成一個索引,比如B-Tree的方式

全文索引

主要用于海量數(shù)據(jù)的搜索,比如淘寶、京東對商品的搜索就可以建立全文索引(不可能用like模糊匹配吧),這個類型在mysql5.6開始支持InnoDB引擎的全文索引,功能沒有專業(yè)搜索引擎比如solr、es豐富,如果需求簡單,可以使用全文索引

適用場景:適用于海量數(shù)據(jù)的關(guān)鍵字模糊搜索,比如簡易版的搜索引擎

索引的實(shí)現(xiàn)方式

B-Tree索引

InnoDB使用的是B-Tree算法,即每個葉子節(jié)點(diǎn)包含指向下一個葉子節(jié)點(diǎn)的指針,就像一個樹一樣


適用場景:最常用的一個索引類型,可以適用于多種場景

工作原理:B-Tree索引中,聯(lián)合索引中的索引項會先根據(jù)第一個索引列進(jìn)行排序,第一個索引列相同的情況下,會再按照第二個索引列進(jìn)行排序,依次類推。

可以應(yīng)用到B-Tree索引的情況:

  • 全值匹配:查找條件和索引中的所有列相匹配
  • 匹配最左前綴:查找條件只有索引中的第一列
  • 匹配列前綴:比如有兩個索引,一個是姓,一個是名,先找到zhang的列,然后再根據(jù)已找到的列找到名為s開頭的人,也可以應(yīng)用到索引
  • 匹配范圍值:比如查找姓在chen到zhang之間的人;或者查找姓為zhang,然后名為san到si范圍的人
  • 只訪問索引的查詢:即要查詢的數(shù)據(jù)都在索引中包含,則只需要訪問索引就行,無需訪問數(shù)據(jù)行,比如只需要查詢姓和名兩列,而這兩列剛好又是聯(lián)合索引。這種索引被稱作覆蓋索引
  • 索引排序:比如使用姓進(jìn)行排序
  • 無法使用到B-Tree索引的情況:

  • 索引不是最左列開始查找,則無法使用索引。比如直接查找名為san的人,則無法應(yīng)用到索引
  • 索引不全:比如有三個字段的聯(lián)合索引,條件中只有第一個、和第三個的字段條件,跳過了中間某個列,則只能使用到索引的第一列
  • 如果查詢中有某個列的范圍查詢,則該列右邊的所有列都無法使用索引優(yōu)化查詢(范圍的話沒有具體的值)。

  • 哈希索引

    如果在列上建立索引,則針對每一行數(shù)據(jù),存儲引擎會根據(jù)所有的索引列計算出一個哈希碼,每一個行計算出的哈希碼會組成一個哈希表,同時在哈希表中存儲了指向每個數(shù)據(jù)行的指針。
    哈希表結(jié)構(gòu)如下:

    適用場景:僅作等值匹配且數(shù)據(jù)重復(fù)率低且對索引查找速度要求高的情況

    可以應(yīng)用到哈希索引的情況:

  • 只有精確匹配全部索引行的查詢條件才能利用索引
  • 無法使用到哈希索引的情況:

  • 索引中不包含任何列的值
  • 索引無法應(yīng)用于排序
  • 不支持部分索引列匹配查找(必須使用全部索引列的查詢條件才能使用哈希索引優(yōu)化查詢)
  • 無法范圍查找,只能等值比較
  • 哈希沖突會影響性能:比如某個列的數(shù)據(jù)重復(fù)率非常高,則每次在找到匹配的哈希后還需要對這個哈希碼的所有數(shù)據(jù)進(jìn)行等值比較
  • 其中,還有一個叫做“自適應(yīng)哈希索引”,是當(dāng)InnoDB注意到某些索引的使用頻率很高時,會在B-Tree索引之上再建立一層哈希索引,以提高查詢效率

    空間數(shù)據(jù)索引(R-Tree)

    空間索引可用于地理數(shù)據(jù)存儲,它需要GIS相關(guān)函數(shù)的支持,由于MySQL的GIS支持并不完
    善,所以該索引方式在MySQL中很少有人使用。

    擴(kuò)展

    什么是回表

    如果 select 所需獲得列中有大量的非索引列,索引就需要到表中找到相應(yīng)的列的信息,這就叫回表

    比如如下例子,先使用普通索引查詢除出ID,然后再去聚簇索引查詢具體數(shù)據(jù)的過程就叫左做回表

    如何避免回表?

    使用聚集索引(主鍵或第一個唯一索引)就不會回表,普通索引就會回表

    比如select id, name, sex from user;,將單列索引(name)升級為聯(lián)合索引(name, sex),即可避免回表,因為要查詢的name和sex都在索引中了

    索引下推

    MySQL 5.6引入了索引下推優(yōu)化,可以在索引遍歷過程中,對索引中包含的字段先做判斷,過濾掉不符合條件的記錄,減少回表字?jǐn)?shù)

    select * from tuser where name like '張 %' and age=10 and ismale=1;

    沒有索引下推:首先根據(jù)索引來查找記錄,然后再根據(jù)where條件來過濾記錄(回表)
    有索引下推:MySQL會在取出索引的同時,判斷是否可以進(jìn)行where條件過濾再進(jìn)行索引查詢(回表)

    唯一索引導(dǎo)致死鎖

    如圖所示,有三個事務(wù)同時插入同一個記錄,導(dǎo)致唯一索引沖突的過程:

    死鎖發(fā)生過程:

  • T1時刻sessionA插入會加排他鎖
  • T2時刻SessionB插入同id會主鍵沖突,會加上共享鎖
  • T3時刻SessionC插入同id會主鍵沖突,會加上共享鎖
  • 這時,SessionA回滾釋放排他鎖,sessionB向獲得排他鎖,但發(fā)現(xiàn)sessionC有共享鎖存在,B和C相互等待造成死鎖
  • 根本原因:
    唯一索引導(dǎo)致,本質(zhì)是并發(fā)請求導(dǎo)致一個數(shù)據(jù)重復(fù)插入或是網(wǎng)絡(luò)抖動造成

    解決方案:

  • 可以使用緩存將重復(fù)請求去重,確保同時只執(zhí)行一個相同sql
  • 異常捕捉,mysql有死鎖檢測和恢復(fù),只有一個事務(wù)會成功,只需要catch異常即可
  • 總結(jié)

    以上是生活随笔為你收集整理的数据库索引类型介绍及其优缺点、区别、适用场景的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。