mysql索引和執行計劃
索引結構
索引都是採用B+樹,允許在同1列上重複建立索引;
唯一性索引可以避免下一行額外掃描,普通索引在找到侯選列後,會讀取下一行判斷其是否依舊滿足查詢條件,狀態變數Handler_read_next記錄相應操作;
InnoDB預設頁大小16K,預設預留1/16的空閒;如果順序插入則填充因子為15/16,隨機插入則為15/16 – ½,即預留空間比較多;
InnoDB二級索引都包含主鍵列,且為最後1位;
更確切的說,當二級索引不包含或包含部分主鍵列時,InnoDB會自動補全所有主鍵列,但Mysql對此不知曉故無法在sql執行時使用;
索引型別
MyISAM支援fulltext索引且僅限於char/varchar/text;
memory表支援hash 索引;
對blob/text列必須建立prefix索引,即取前N個位元組,字首最大可為1000(InnoDB則為767);
不支援基於函式的索引;
Mysql分割槽只支援本地索引;
InnoDB快速建立索引
在之前的版本中,建立索引必須建立一張臨時表,然後更新臨時表後將原表刪除,最後重新命名臨時表,比較耗時;
這個過程很低效,因此5.5(包括採用plugin的5.1)引入一個新功能,叫做fast index creation,僅適用於二級索引;
其直接在原表的基礎上建立索引,從而廢除了臨時表的使用,在建立過程中原表新增共享鎖,不阻塞讀操作,且索引頁的填充率即fill factor更高;
注:如果重建聚集索引,依舊採用重建copy的方式,原表加排他鎖,阻塞所有操作;
如果需要建立多個二級索引,可以呼叫alter table add index一次性執行,避免多次掃描表;
在二級索引快速建立時,需要向$TMPDIR目錄寫臨時檔案;
當呼叫alter table … rename column時,為避免innodb和mysql資料字典不一致,依舊採用重建+copy的方法;
5.5版本暫不對foreign key提供此功能;
此功能僅支援InnoDB,故MyISAM依舊採用建立臨時表 + copy的方式建立索引,但可透過調優幾個引數加速索引的建立:
Myisam_max_sort_file_size:重建MyISAM索引允許使用的臨時檔案最大尺寸,如果超出了此規定值,就改用key cache效率就會比較慢;預設2G;
Myisam_sort_buffer_size:用於排序的buffer大小,repair table或建立索引時用到;
key_buffer_size
倘若碰到比較變態的大表,則可採用曲線救國的方法:
案例
為超過1.8億條資料的表建立索引
需用到memory/merge表,也可使用分割槽替代;
首先將max_heap_table_size/tmp_table_size調大至4G或更大(視自身伺服器而定),用於儲存記憶體表;
建立記憶體表,透過insert … select將原表資料裝入記憶體表(假定1次可裝載1千萬行),建立索引;如果只有幾千萬行,可以為記憶體表新增索引然後透過insert … select將其重新整理至目標表,反覆幾次即可;
建立18個merge表,insert … select將資料加入記憶體表 à insert … select從記憶體表重新整理至merge表 à truncate記憶體表 反覆18次;
建立一個merge表整合18個表,然後insert … select from merge_table order by index1, index2將此表重新整理至目標表即可;
索引Hint
Using index –指定所用索引
Straight_join – 強制表連線順序
查詢涉及的表越多,最佳化器搜尋最佳執行計劃的時間就會越長,可透過如下兩個引數控制解析時間:
Optimizer_prune_level: 預設為0,設定為1時最佳化器估算每個表返回行數進而自動過濾掉一些執行計劃,但也有可能漏掉最優的
Optimizer_switch
5.1引入此引數,主要用於控制index merge http://dev.mysql.com/doc/refman/5.1/en/index-merge-optimization.html
mysql> SELECT @@optimizer_switch\G
*************************** 1. row ***************************
@@optimizer_switch: index_merge=on,index_merge_union=on,
執行計劃
使用explain可檢視sql執行計劃
其輸出包含多個列,比較重要的如下
Key_len:使用到的索引鍵的位元組長度,其受資料型別,字符集以及not null影響;Null +1位元組;varchar + 2位元組;
長度 |
資料型別及約束 |
4 |
Int not null |
5 |
Int null |
30 |
Char(30) not null |
32 |
Varchar(30) not null |
92 |
Varchar(30) null charset=utf8 |
3 |
Date |
4 |
timestamp |
8 |
datetime |
Select type
SIMPLE |
|
PRIMARY |
Outermost SELECT |
DEPENDENT UNION |
Second or later SELECT statement in a UNION, dependent on outer query |
UNION RESULT |
Result of a UNION. |
SUBQUERY |
First SELECT in subquery |
DEPENDENT SUBQUERY |
First SELECT in subquery, dependent on outer query |
DERIVED |
Derived table SELECT (subquery in FROM clause) |
UNCACHEABLE SUBQUERY |
A subquery for which the result cannot be cached and must be re-evaluated for each row of the outer query |
UNCACHEABLE UNION |
The second or later select in a UNION that belongs to an uncacheable subquery (see UNCACHEABLE SUBQUERY) |
Eq_ref: inner table使用主鍵或unique index,而outer table可能返回多行
Ref: 類似eq_ref,不同的是inner table使用普通索引或聯合主鍵的前幾列
Unique_subquery: 在某些in子查詢中替代ref value in (select primary_key from table where expr)
Extra
using index使用覆蓋索引;
using temporary使用了基於記憶體的臨時表,1個query可引用多個,一旦達到限定條件就建立於磁碟上;
using filesort—order by 引起的排序;
using join buffer在join時沒有使用索引並且需要join buffer儲存中間結果;
impossible where--where語句會導致沒有符合條件的行;
distinct—mysql在找到第一個匹配行後就停止搜尋;
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15480802/viewspace-757967/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle 索引和執行計劃Oracle索引
- mysql 執行計劃索引分析筆記MySql索引筆記
- 【MySQL】MySQL的執行計劃及索引優化MySql索引優化
- 【Oracle】-【索引-HINT,執行計劃】-帶HINT的索引執行計劃Oracle索引
- 理解索引:MySQL執行計劃詳細介紹索引MySql
- MySQL 執行計劃MySql
- MySQL執行計劃MySql
- clustering factor索引聚簇因子和執行計劃索引
- mysql執行計劃explainMySqlAI
- mysql explain 執行計劃MySqlAI
- MySQL執行計劃解析MySql
- MySQL:2020 端午節隨筆(索引下探和唯一索引特殊執行計劃)MySql索引
- MySQL執行計劃解析(四)MySql
- 讀懂MySQL執行計劃MySql
- 讀懂 MySQL 執行計劃MySql
- Oracle訪問索引的執行計劃(一)Oracle索引
- Oracle訪問索引的執行計劃(二)Oracle索引
- Oracle訪問索引的執行計劃(三)Oracle索引
- Oracle訪問索引的執行計劃(四)Oracle索引
- Oracle訪問索引的執行計劃(五)Oracle索引
- 建立索引調整sql的執行計劃索引SQL
- 關於索引的執行計劃記載索引
- 帶你看懂MySQL執行計劃MySql
- MySQL Explain執行計劃 - 詳解MySqlAI
- 十六、Mysql之Explain執行計劃MySqlAI
- mysql explain 執行計劃詳解MySqlAI
- MySQL執行計劃EXPLAIN詳解MySqlAI
- 建了索引執行計劃會有區別了索引
- 索引及排序對執行計劃的影響索引排序
- MySQL 因資料型別轉換導致執行計劃使用低效索引MySql資料型別索引
- mysql調優之——執行計劃explainMySqlAI
- (4) MySQL中EXPLAIN執行計劃分析MySqlAI
- mysql主從庫執行計劃不同MySql
- MySQL中in(常量列表)的執行計劃MySql
- 執行計劃-1:獲取執行計劃
- 分割槽索引(Partition Index)與SQL執行計劃(中)索引IndexSQL
- 分割槽索引(Partition Index)與SQL執行計劃(下)索引IndexSQL
- 分割槽索引(Partition Index)與SQL執行計劃(上)索引IndexSQL