MySQL中的索引——概念篇

使用索引的目的

使用索引的目的是提高數據庫查詢的效率。索引是怎么提高數據庫查詢的效率的呢?舉個通俗的例子,查字典。數據庫中的數據就好比新華字典中的詞條,索引就是新華字典的目錄。沒有建立索引的數據庫就好像被撕掉目錄的新華字典,只能從頭到尾一條一條地查詢,效率極其低下。

為了能更快地查字典,哦不,是查詢數據庫,我們就需要為數據庫建立索引。

索引的原理

索引的主要思想是將數據分段,從而減少查詢時的無效數據,提高查詢效率。比如有1000條數據,1到100分成第一段,101到200分成第二段,201到300分成第三段……這樣查第250條數據,只要找第三段就可以了,一下子去除了90%的無效數據。

當然,上面只是主要思想,MySQL使用了更加具體的數據結構來實現索引。本文不對索引的數據結構展開討論。

建立索引的幾大原則

如何建立合適的索引,從而最大程度地優化查詢效率是一件需要精心設計的事情。本節只介紹幾個建立索引時須遵循的原則。

  1. 最左前綴匹配原則,非常重要的原則。mysql會一直向右匹配直到遇到范圍查詢><betweenlike就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4如果建立(a,b,c,d)順序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引則都可以用到,a,b,d的順序可以任意調整。關于最左前綴匹配原則,在最左前綴匹配原則一節有詳細說明。
  2. 盡量選擇區分度高的列作為索引,區分度公式為count(distinct col)/count(*),即一列中內容不同的記錄數占總記錄數的比例。通過這個公式我們可以得到字段不重復的比例,比例越大我們掃描的記錄數越少,唯一鍵的區分度是1,而一些狀態、性別字段可能在大數據面前區分度就是0。所以唯一索引的效率是最高的。在不是唯一鍵的時候,就要具體情況具體分析了,這也是索引設計的關鍵點之一。
  3. 索引列不能參與計算,保持列“干凈”,比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很簡單,索引的數據結構中存的都是數據表中的字段值,但進行檢索時,需要把所有元素都應用函數才能比較,顯然成本太大。所以語句應該寫成create_time = unix_timestamp(’2014-05-29’);
  4. 盡量的擴展索引,不要新建索引。比如表中已經有a的索引,現在要加(a,b)的索引,那么只需要修改原來的索引即可
  5. 使用短索引。如果對串列進行索引,應該指定一個前綴長度,只要有可能就應該這樣做 。
    例如,如果有一個 CHAR(200) 列,如果在前 10 個或 20 個字符內,多數值是惟一的,
    那么就不要對整個列進行索引。對前 10 個或 20 個字符進行索引能夠節省大量索引空
    間,也可能會使查詢更快。

最左前綴匹配原則

最左前綴使用場景是使用復合索引的時候。當使用復合索引時,如果想要索引有效,where之后的表達式就要滿足最左前綴匹配原則。

我總結了一下最左前綴匹配的特點,就是從表達式最左邊開始,到第一個范圍查詢結束,在這個閉區間內的字段應該是索引字段的最左前綴

最左前綴

在這里解釋一下最左前綴,因為沒有百度到感覺比較靠譜的解釋,所以我在這里談一下我的理解,僅供參考。

前綴應該不用解釋了,學過英語的都該懂點。前綴加個就是左前綴了,表示從左邊開始查找的前綴。但是,這個左只是表示查找的順序是從左邊開始,不是從右邊開始,并沒有說從哪一位開始,可能是第一位,也可能是第三位。這時候再加一個 就表示了從最左邊開始。

比如復合索引是(a,b,d,c),那么查詢時表達式的字段順序為(a)、(a,b)、(a,b,d)、(a,b,d,c)的這些都是它的最左前綴,而(b)、(a,d)、(a,b,c)、(a,b,c,d)這些就不是。

關于MySQL的查詢優化器

最左前綴的概念我們已經明白了,但是在MySQL中的情況又有點不同。比如我們發現,索引的順序是(a,b,d,c),我們的查詢條件是這樣寫的:where b=10 and c=16 and a=26 and d=0,從嚴格意義上來講,這個順序是不符合最左前綴匹配原則的,但是MySQL的確使用索引完成了查詢。這是怎么回事呢?這是因為MySQL的查詢優化器幫我們調整了查詢條件的順序。MySQL查詢優化器會判斷糾正一條sql語句該以什么樣的順序執行效率最高,最后才生成真正的執行計劃。在有索引的情況下當然是利用索引查詢順序的效率最高咯,所以,MySQL查詢優化器會最終以索引的順序進行查詢執行。

最左前綴匹配原則的原理

上面說了這么多的最左前綴的概念,那么我們到底為什么一定要符合最左前綴匹配原則呢?

因為復合索引只有第一個字段是絕對有序的,從第二個開始的字段都只是相對前一個字段有序,在全局范圍內是無序的。只有滿足最左前綴原則,才可以保證查詢內容的有序,而有序又是索引使用的前提。

我們來看個例子,以該表的(name,cid)復合索引為例,它內部結構簡單說就是下面這樣排列的:

name cid
a 6
c 4
c 5
h 1
z 9

MySQL創建復合索引的規則是首先會對復合索引的最左邊的,也就是第一個name字段的數據進行排序,在第一個字段的排序基礎上,然后再對后面第二個的cid字段進行排序。其實就相當于實現了類似 order by name cid這樣一種排序規則。

第一個name字段是絕對有序的,而第二字段就是無序的了。所以通常情況下,直接使用第二個cid字段進行條件判斷是用不到索引的。

那么什么時候才能用到呢?當然是cid字段的索引數據也是有序的情況下才能使用咯,什么時候才是有序的呢?觀察可知,當然是在name字段是等值匹配的情況下,cid才是有序的。發現沒有,觀察兩個name名字為 ccid字段是不是有序的呢。從上往下分別是4 5。這也就是MySQL索引規則中要求復合索引要想使用第二個索引,必須先使用第一個索引的原因(最左前綴匹配原則)。

補充使用索引時的具體情況

更多使用索引的詳細情況,可以參考最左前綴原理與相關優化

本文的參考資料

http://blog.jobbole.com/86594/

https://www.zhihu.com/question/36996520/answer/93256153

http://www.kancloud.cn/kancloud/theory-of-mysql-index/41857

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,732評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,214評論 3 426
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,781評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,588評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,315評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,699評論 1 327
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,698評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,882評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,441評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,189評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,388評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,933評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,613評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,023評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,310評論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,112評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,334評論 2 377

推薦閱讀更多精彩內容