1. 程式人生 > >MySQL索引設計需要考慮哪些因素?

MySQL索引設計需要考慮哪些因素?

索引小知識

篇幅有限,索引的基本知識我們就不贅述了,在此,我們嘗試說明其中的一個小點-----B+樹與B樹的區別到底是什麼。

InnoDB是使用B+樹來實現其索引功能的。在B+樹中,內節點(非葉子節點)儲存了行資料的鍵,而葉子節點儲存了所有的行資料,而B樹的每個節點都儲存了真實的資料。這種資料結構,決定了兩者有以下不同點:

(1)非葉子節點能存放指標的資料量。因為B樹的非葉子節點存放的是整行的資料,佔用了較多的空間,所以能存放指標就相對較少,因此整個B樹的層數就變高。當資料量比較大時,插入更新會導致維護代價也是比較大的,而且層數越高,搜尋的效能就會越低。而B+樹的內節點存放的是相對短很多的鍵值,就克服了B樹遇到的問題。

(2)從資料結構上來看,B樹的查詢效率與資料所在的位置有關。即如果所要搜尋的資料節點,在樹上的位置,越靠近根節點,查詢返回結果越快,最差的就是資料位於葉子節點上,不同的節點位置,其效能不均衡;而B+樹,完整的資料都是在葉子節點上,其查詢效率是固定的。插入、刪除操作同樣的原理,在B樹中,其複雜度明顯增加,而B+樹相對簡單的多。例如,B+樹,在插入過程中,只需要通過在每一層搜尋一個節點,依次找到節點之後,在節點處插入即可(節點滿,則分裂)。

(3)B樹中,所有的資料只儲存了一份;而B+樹,除了儲存了所有資料的葉子節點外,還要在內節點儲存了鍵值。所以,在空間佔用方面,B+樹會比B樹多些。

(4)在一個表中,聚族索引佔用的空間肯定是最大的,因為它儲存了全部資料,而二級索引是建立在某幾個經常查詢的列上(還有用來“回表”的指標),所以,二級索引的佔用空間都會比聚族索引小很多。

索引設計原則

(1)MySQL 表主鍵設計

INNODB 以主鍵排序儲存;聚集索引只能是主鍵;儲存所有資料;二級索引包含主鍵鍵值。

如果表沒有定義主鍵,會選擇第一個唯一索引(非空)作為聚集索引主鍵。如果唯一索引也沒有,MySQL後臺會自動生成RowID。

字元型別欄位最好不要做主鍵;常見的主鍵有兩種:自增列和UUID。

自增:  順序儲存,索引維護成本低,索引效率高;

UUID:非順序增長,隨機IO嚴重。

(2)索引並不是越多越好,要根據查詢,有針對性的建立,考慮在WHERE和ORDER BY命令上涉及的列建立索引,可根據EXPLAIN來檢視是使用了索引還是全表掃描;

(3)應儘量避免在WHERE子句中對欄位進行NULL值判斷,否則將導致引擎放棄使用索引而進行全表掃描;

(4)值分佈很稀少的欄位不適合建索引,例如“性別”這種只有兩三個值的欄位;

(5)不用外來鍵,由程式保證約束;

(6)儘量不用UNIQUE,由程式保證約束;

(7)使用多列索引時主意順序和查詢條件保持一致,同時刪除不必要的單列索引。

(8)排序時,排序欄位需要注意index, 尤其是關聯查詢排序時,儘可能使用小表的欄位進行排序

SQL 優化 原則

(1)避免屬性隱試轉換 , 如定義Moblie varchar  where Moblie =198989888會導致全表掃描;

(2)Where子句中條件欄位本身避免使用函式;

(3)使用獲取的必要欄位代替SELECT *;

(4)批量插入,使用INSERT INTO table (col1,col2,...) VALUES (value1, value2,...),(value1, value2,...); 插入多條資料只有一次提交;

(5)避免使用長事務;

(6)禁止負向查詢: NOT、!=、<>、!<、!>、NOT IN、NOT LIKE,會導致全表掃描;

(7)大表之間的join,儘量縮小結果集之後再join,否則會消耗較多的記憶體和CPU;

(8)搜尋嚴禁左模糊或者全模糊(like %XX, 或like %XX%),會導致全表掃描。