一、索引
正確的創建合適的索引是提升數據庫查詢性能的基礎。
索引是什麼
官方正解:數據本身之外,數據庫還維護着一個滿足特定查找算法的數據結構,這些數據結構以某種方式指向數據,這樣就可以在這些數據結構的基礎上實現高級查找算法,這種數據結構就是索引。
索引本身也很大,不可能全部在內存中,往往以索引文件的形式存儲在磁盤上。
索引的本質
一種可以幫mysql高效的獲取數據的數據結構。
索引查的快的根本原因是因爲已經排好序了(B+tree葉子節點有序)
索引的優劣勢分析
索引優勢
- 減少存儲引擎需要掃描的數據量,提高數據檢索效率,降低數據庫的IO成本
- 通過索引列對數據進行排序,降低數據排序的成本,降低了CPU的消耗(索引已有序)
- 在分組,排序等操作時可以避免使用臨時表
索引劣勢
- 索引也是一張表,保存了主鍵和索引字段,並指向實體表的記錄,索引列也會佔空間
- 降低更新表的速度,寫操作時不僅要保存數據,還要保存索引字段,每次更新索引列都會調整索引信息
索引分類
- 聚集索引:一張表只有一個聚集索引,如果沒有定義主鍵,innodb會選擇一個唯一的非空索引代替。如果沒有這樣的索引,innodb會隱式創建一個主鍵作爲聚集索引。
- 唯一索引: 一張表可以多個唯一索引,索引列的值必須唯一,但允許有空值,(身份證號,手機號等具有唯一標識的都可以建立唯一索引)
- 單值索引(頻繁的根據某個字段來更新)
- 複合索引:一個索引包含多個列
索引結構
- hash索引
- full-text 全文索引
- R-Tree索引
- BTree索引(mysql-innodb默認索引)
- 樹的廣度竟儘可能廣,層級儘可能少,層級少,減少IO操作
索引使用
適合建立索引的情況:
主鍵自動建立唯一索引
頻繁做爲查詢條件的字段
與其他表做外鍵關聯的字段
單/複合索引選擇問題(高併發下傾向於創建組合索引)
查詢中排序的字段,排序字段通過索引去訪問將大大提高排序速度
統計或分組字段(分組的前提是排序)
不適合建立索引的情況:
- 頻繁更新的字段
- where條件裏用不到的
- 表記錄太少
- 數據重複率高的字段(eg: 性別:男/女); 一個索引的選擇性越接近於1,離散性越高效率越高
二、Explain分析
Explain是什麼?
可以查看執行計劃,模擬優化器執行SQL,從而知道mysql是如何處理我們的sql的。
Explain能查看什麼?
- 查看錶達讀取順序
- 數據讀取操作的操作類型
- 哪些索引可以使用 --possible_keys
- 哪些索引被實際使用–key
- 表之間的引用
- 每張表有多少行被優化器查詢
Explain各字段分析
id(表的讀取順序)
select查詢的序列號, 標識執行的順序
1、 id相同, 執行順序由上至下
2、 id不同, 如果是子查詢, id的序號會遞增, id值越大優先級越高, 越先被執行
3、 id相同又不同即兩種情況同時存在, id如果相同, 可以認爲是一組, 從上往下順序執行; 在所有組中, id值越大, 優先級越高, 越先執行
select_type (數據讀取操作的操作類型)
6中操作類型:
table(查詢涉及到的表)
直接顯示錶名或者表的別名
<unionM,N> 由ID爲M,N 查詢union產生的結果
由ID爲N查詢生產的結果
type (訪問類型)
結果值好壞依次是:
system > const > eq_ref > ref > range > index > ALL
一般情況下,需要保證查詢至少達到range級別,最好能達到ref.
possible_keys ( 可能被用到的索引)
key (最後實際用到的索引)
如果爲null,表示沒用使用索引
key_len (索引中使用的字節數)
可通過該列計算查詢中使用的索引長度,在不損失精度的情況下,越短越好。
key_len與精度矛盾,越短精度越低
ref
顯示索引的哪一列被使用了,如果可能的話,是一個常數,
rows
每張表有多少行被優化器查詢,大致估算出找到所需的記錄所需要讀取的行數
extra
包含不適合在其他列中顯示但十分重要的額外信息