索引應該是各種資料庫優化方案之中成本最低,見效最快的解決方案了,現在就重點講下:企業級應用如何構建高效索引,以及應該注意些什麼。
索引類型
1、B-tree索引
Myisam和innodb中,默認用B-tree索引,是一種平衡樹。可以抽象一下---B-tree系統,可理解為"排好序的快速查找結構」
2、hash索引
在memory表裡,默認是hash索引, hash的理論查詢時間複雜度為O(1)
既然hash的查找如此高效,為什麼不都用hash索引?
1:hash函數計算後的結果,是隨機的,沒有辦法對範圍查詢進行優化.
2: 無法利用前綴索引. 比如 在btree中, field列的值「hellopworld」,並加索引
查詢 xx=helloword,自然可以利用索引, xx=hello,也可以利用索引. (左前綴索引)
因為hash(『helloword』),和hash(『hello』),兩者的關係仍為隨機
3: 排序也無法優化.
4: 必須回行。就是說通過索引拿到數據位置,必須回到表中取數據
以下是建立索引時的注意事項
1.索引不是越多越好,單張表中索引數量不宜超過8個合理創建聯合索引,(a,b,c) 相當於 (a) 、(a,b) 、(a,b,c)禁冗餘索引
索引是雙刃劍,會增加維護負擔,增大IO壓力。(a,b,c)、(a,b),後者為冗餘索引。可以利用前綴索引來達到加速的目的,減輕維護負擔
2.SELECT只獲取必要的欄位,不建議使 SELECT *
好處:減少網絡帶寬消耗;能有效利用覆蓋索引,表結構變更對程序基本無影響
3.合理使用覆蓋索引減少IO,避免排序
4.索引覆蓋是指如果查詢的列恰好是索引的一部分,那麼查詢只需要在索引文件上進行,不需要回行到磁碟再找數據。這種查詢速度非常快,稱為"索引覆蓋」
理想的索引:1:查詢頻繁 2:區分度高 3:長度小 4: 儘量能覆蓋常用查詢欄位
註:主鍵查詢是天然的覆蓋索引
5.儘量避免用NULL()
原因: NULL不利於索引,要用特殊的字節來標註。在磁碟上佔據的空間其實更大。
6.索引的主鍵值,應儘量是連續增長的值,而不是要是隨機值(不要用隨機字符串或UUID),否則會造成大量的頁分裂與頁移動
7.不對過的VARCHAR欄位建立索引。建議優先考慮前綴索引,或添加CRC32或MD5偽列並建立索引
8.在常用的列上加上適當索引
例: where cat_id=3 and price>100 ; //查詢第3個欄目,100元以上的商品
誤: cat_id上,和, price上都加上索引.
錯: 只能用上cat_id或Price索引,因為是獨立的索引,同時只能用上1個
9.多列索引上,索引發揮作用,需要滿足左前綴要求
以 index(a,b,c) 為例
10.選擇區分度大的列建立索引。
組合索引中,區分度大的欄位放在最前重要SQL必須被索引:update、delete的where條件列、order by、group by、distinct欄位、多表join欄位。
11.不建議使用%前導查詢,例如:like「%abc」,無法利用到索引。
12.不建議使用負向查詢,例如notin、!=、notlike。使用EXPLAIN判斷SQL語句是否合理使用索引,儘量避免extra列出現:Using File Sort、Using Temporary