1. 索引分類
- 單值索引: 一個索引只包含單個列, 一個表可以有多個單列索引, 單值索引一次查詢只能用一個
- 唯一索引: 索引列的值必須唯一, 但允許有空值
- 複合索引: 一個索引包含多個列
2. 索引創建/刪除
- 創建:
CREATE [UNIQUE] INDEX idx_mytable_colname ON mytable(colname(length))
- 添加:
ALTER mytable ADD [UNIQUE] INDEX idx_mytable_colname ON
(colname(length))
- 刪除:
DROP INDEX [idx_mytable_colname] ON mytable
- 查看:
SHOW INDEX FROM mytable
3. 四種添加索引的方式
- 添加一個主鍵, 也就是說添加一個不能爲空的唯一索引
ALTER TABLE tbl_name ADD PRIMARY KEY (column_list)
ALTER TABLE tbl_name ADD UNIQUE index_name(column_list)
ALTER TABLE tbl_name ADD INDEX index_name(column_list)
ALTER TABLE tbl_name ADD FULLTEXT index_name(column_list)
4. 索引結構
- BTree索引
- Hash索引
- full-text全文索引
- R-Tree索引
5. 需要創建索引的情況
- 頻繁作爲查詢條件的字段應該創建索引
- 查詢中與其它表關聯的字段, 外鍵關係建立索引
- 高併發下傾向創建組合索引
- 經常排序的字段最好建索引
- 查詢中統計或者分組的字段建索引
6. 不應建索引的情況
- 頻繁更新的字段
- where條件裏用不到的字段
- 包含很多重複內容且分佈均勻的字段
- 表記錄很少的情況
7. MySQL常見瓶頸
- 語句有問題
- CPU: CPU飽和, 一般發生在數據裝入內存或從磁盤上讀取數據的時候
- IO: IO瓶頸發生在裝入數據遠大於內存容量的時候
- 服務器硬件瓶頸: top, free, iostat, vmstat 等查看系統性能
8. Explain 解析
- 顯示內容:
- 表的讀取順序
- 數據讀取操作的操作類型
- 哪些索引可以使用
- 哪些索引被使用
- 表之間的引用
- 每張表有多少行被優化器查詢
- 返回結果包含字段
- id select 查詢的系列號, 包含一組數字, 表示查詢中執行select子句或操作表的順序
三種情況:
- id相同, 執行順序由上至下
- id全不同, id越大優先級越高,越先執行
- id部分相同, 優先執行跟順序執行並存
- select_type 查詢的類型, 主要用於區分普通查詢/聯合查詢/子查詢等複雜查詢
六種返回結果:
- SIMPLE 簡單的select查詢, 不包含子查詢或UNION
- PRIMARY 查詢中若包含任何複雜子部分, 表示最外層查詢
- SUBQUERY 在select或where列表中包含子查詢
- DERIVED 在from列表中包含的子查詢被標記爲DERIVED, MySQL會遞歸執行這些子查詢, 把結果放在臨時表中
- UNION 若第二個select出現在UNION之後, 則被標記爲UNION, 若UNION包含在FROM子句的子查詢中, 外層select被標記爲DERIVED
- UNION RESULT 從UNION表獲取結果的select
- table 表名
- type 訪問類型, 顯示查詢使用了何種類型,
最好到最差依次是: system>const>eq_ref>ref>range>index>ALL
- system 表只有一行數據(等於系統表), 是const類型的特例, 平時不會出現
- const 表示通過一次索引就找到了, 用於比較primary key或者unique索引. 因爲只匹配一行數據, 所以很快, 如將主鍵置於where列表, MySQL就能將該查詢轉換爲一個常量
- eq_ref 唯一性索引掃描, 對於每個索引鍵, 表中只有一條記錄與之匹配. 常見於主鍵或者唯一索引掃描
- ref 非唯一索引掃描, 返回匹配某個單獨值的所有行. 本質上也是一種索引訪問, 屬於查找和掃描的混合體
- range 只檢索給定範圍的行, 使用一個索引來選擇行.
- index 只遍歷索引
- ALL 全表掃描
- possible_keys 系統推測可能應用在這張表中的索引, 不一定被實際使用
- key 實際使用的索引, 如果爲NULL, 表示沒有使用索引, 查詢中若使用了覆蓋索引, 則該索引僅出現在key列表中
覆蓋索引是指創建與使用的聯合索引剛好完全一致
- key_len 表示索引中使用的最大可能字節數, 時根據表定義計算得到的, 不是表內檢索出的, 在不損失精度的情況下, 長度越短越好
- ref 顯示索引的哪一列被使用, 是一個常數
- rows 顯示每張表有多少行被優化器查詢過
- Extra - Using filesort 文件排序 說明MySQL不是按照表內索引順序讀取, 而是使用了一個外部索引排序, 這是比較危險的情況
- Using temporary 對查詢結果排序時使用了臨時表保存結果, 常見於order by和group by, 使用group by時一定要保證字段與索引順序一致
- Using index 表示使用了覆蓋索引, 如果同時出現using where表明索引被用來執行索引鍵值的查找, 如果沒有出現using where表明索引被用來讀取數據而非執行查找動作. 覆蓋索引是指, select的字段剛好跟建索引的字段一樣且順序一致, 換句話說, 查詢列被所建索引覆蓋, 所需數據直接從索引中獲取即可
- Using where 表明使用了where搜索
- Using join buffer 使用了連接緩存, 這是可以把join緩存區調大
- impossible where where語句返回false
- select tables optimized away 在沒有group by子句的情況下, 基於索引優化min/max操作
- distinct
9. 索引優化需要注意問題:
- 如果對範圍查詢的字段使用索引, 其後的索引將失效
- 建組合索引時, 要保證索引順序與字段的使用順序一致, 否則索引可能失效, 對於orderby字段,失效的標誌是extra中顯示Using filesort
- 要想覆蓋索引生效, 一定不能使用select *來取數, 而是要從索引列取數
- 兩表關聯時, 左連接的話要在右表建索引, 右連接在左表建索引
- join 優化時要注意: 1.使用小表驅動大表, 2.優先優化內層循環, 3.保證join語句中被驅動表上join字段已經被索引, 4.調整joinbuffer大小