1. 程式人生 > >mysql索引優化的前篇(一)

mysql索引優化的前篇(一)

前言:

由一個索引降維引發的思考炸彈。關於MySQL索引的好處,如果正確合理設計並且使用索引的MySQL是一輛蘭博基尼的話,那麼沒有設計和使用索引的MySQL就是一個人力三輪車。沒有對比就沒有傷害。對於沒有索引的表,單表查詢可能幾十萬資料就是瓶頸,而通常大型網站單日就可能會產生幾十萬甚至幾百萬的資料,沒有索引查詢會變的非常緩慢。

個人理解:

MySQL索引是一種資料結構,可以是BTREE,RTREE,或者HASH結構.
BTREE適合用於查詢某範圍內的資料,可以很快的從當前資料找到下條資料.
RTREE常用於查詢比較接近的資料.
HASH結構則適用於隨機訪問的場合,查詢每條資料的時間幾乎相同.
顯然,若要查詢某個時間段的資料,用BTREE結構要比HASH結構快得多.
另外還有FULLTEXT(全文)和SPATIAL(空間)這兩個索引型別

一、簡單說下大概邏輯下幾個常有的索引:

  • 唯一索引

    與普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值(注意和主鍵不同)。如果是組合索引,則列值的組合必須唯一,建立方法和普通索引類似。

  • 普通索引

    這是最基本的索引,它沒有任何限制,比如上文中為title欄位建立的索引就是一個普通索引,MyIASM中預設的BTREE型別的索引,也是我們大多數情況下用到的索引。

  • 組合索引(最左原則)

    平時用的SQL查詢語句一般都有比較多的限制條件,所以為了進一步榨取MySQL的效率,就要考慮建立組合索引。建立這樣的組合索引,其實是相當於分別建立了下面兩組組合索引

插語:

雖然索引有利於查詢搜尋,但過多的使用索引將會造成濫用。因此索引也會有它的缺點:雖然索引大大提高了查詢速度,同時卻會降低更新表的速度,如對錶進行INSERT、UPDATE和DELETE。因為更新表時,MySQL不僅要儲存資料,還要儲存一下索引檔案。建立索引會佔用磁碟空間的索引檔案。一般情況這個問題不太嚴重,但如果你在一個大表上建立了多種組合索引,索引檔案的會膨脹很快。索引只是提高效率的一個因素,如果你的MySQL有大資料量的表,就需要花時間研究建立最優秀的索引,或優化查詢語句。

二、下面是一些總結以及收藏的MySQL索引的注意事項和優化方法:

下面引用一張圖解釋下:

1. 何時使用聚集索引或非聚集索引?

這裡寫圖片描述

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

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

3. 使用短索引

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

4. 索引列排序

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

5. like語句操作—最左原則可使用得到

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

6. 不要在列上進行運算–因為會使得索引失效

例如:select * from users where YEAR(adddate)<2007,將在每個行上進行運算,這將導致索引失效而進行全表掃描,因此我們可以改成:select * from users where adddate<’2007-01-01′。關於這一點可以圍觀:一個單引號引發的MYSQL效能損失。

7、索引降維思想

這個需要在不同場景進行考慮,當使用多個單列索引的時候,因為mysql查詢的時候只能用一個索引,索引這個時候就要考慮下條件,如果不需要組合索引,那麼使用單列索引,在這些單列索引中,你要考每個條件對查詢的影響,例如:一個月內,有一萬個賬戶,每天打出三萬通話記錄,可知,單使用者的通話頻度不高,因此,先定位phone索引集再排除時間的搜尋方式,肯定比先定時間再定賬戶的效率高。
==注:這是特定場景!!!具體請以explain與profiling去分析,MYSQL的執行直譯器,沒有這麼簡單。==

8、組合索引最左原則

使用組合索引的時候也需要考慮沒個索引欄位的排序,在查詢的時候最左的欄位需要是第一個欄位,若不是,則索引不生效,索引匹配的時候會單遇到>= /<= 就會停止匹配,但這裡並不代表>=不能使用索引

最後後總結一下:

MySQL只對一下操作符才使用索引:<,<=,=,>,>=,between,in,以及某些時候的like(不以萬用字元%或_開頭的情形)。而理論上每張表裡面最多可建立16個索引,但索引不是越多越好,要在合適的地方合適的場景用到,切記切記。

備註:後續內容會不斷更新