首先看一下MySQL追蹤優化器的典型用法:
打開:
SET optimizer_trace="enabled=on";
查詢優化器的信息:mysql
SELECT * FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;
關閉:sql
SET optimizer_trace="enabled=off";
默認狀況下是關閉的,要使用的時候必定要打開這個優化器。json
看一下參數:
enabled:打開或者關閉跟蹤器
one_line:若是ON的話將會以JOSN的存儲方式保存跟蹤,可是閱讀的話就是比較費勁的,除了能節省空間沒啥好處,不過仍是建議使用這個方式。
看一下優化器的相關參數,也可使用mysqld --verbose --help查看:
--optimizer-trace=name 控制優化的跟蹤
--optimizer-trace-features=name Enables/disables tracing of selected features of the Optimizer: optimizer_trace_features=option=val[,option=val...], where option is one of {greedy_search, range_optimizer, dynamic_range, repeated_subselect} and val is one of {on, off, default}
--optimizer-trace-limit=# 顯示優化追蹤器的最大數量
--optimizer-trace-max-mem-size=# 存儲優化的痕跡容許的最大尺寸累積
--optimizer-trace-offset=# Offset of first optimizer trace to show; see manual --end-markers-in-json=#
In JSON output ("EXPLAIN FORMAT=JSON" and optimizer trace), if set to 1, repeats the structure's key (if it has one) near the closing bracke
並且這個是和前面所說的information_schema.OPTIMIZER_TRACE表是相對應的
SET GLOBAL optimizer_trace="one_line=on";
打開追蹤優化器優化
而後作一條操做就能看到具體的追蹤優化器的信息了,經過如下的語句進行查詢:
select * from information_schema.OPTIMIZER_TRACE\G;
看一下這張表的結構:spa
看一下字段信息:
QUERY :查詢語句
TRACE :跟蹤信息,是以JSON形式存儲的
MISSING_BYTES_BEYOND_MAX_MEM_SIZE:
INSUFFICIENT_PRIVILEGES
追蹤優化器能夠跟蹤不少信息,SELECT insert,replace(其值或選擇) ; UPDATE / DELETE和multi-table variants;全部EXPLAIN前綴之前的; SET(除非它操縱optimizer_trace系統變量) ;作; DECLARE / CASE / IF / RETURN(存儲程序語言元素) ;call。若是這些語句之一被製備並在分開的步驟中執行,preparation 和execution單獨跟蹤
通常狀況下,一個新的跟蹤都會覆蓋掉之前的跟蹤,特別是對於執行的語句,只能在最新的跟蹤器中生成,老的跟蹤器是不會產生的,這就是覆蓋原則。因此咱們須要對追蹤優化器進行淨化。看一下下面的語句:
SET optimizer_trace_offset=<OFFSET>, optimizer_trace_limit=<LIMIT>
經過上面的語句進行淨化。optimizer_trace_offset和optimizer_trace_limit的默認值分別爲-1和1.這個參數設置指的是什麼呢:
1:當用戶退出後全部的跟蹤信息都會被清除
2:若是OFFSET 是大於0的相同的查詢會返回到第一次查詢的記錄信息,OFFSET 是小於0的話這條記錄就會被記錄下來。
例如咱們將設置如下信息的話:
OFFSET=-1 and LIMIT=1 最後一次查詢信息將會被記錄下來
OFFSET=-2 and LIMIT=1將會記錄下一個到最後的查詢信息
OFFSET=-5 and LIMIT=5 將會記錄最後五次查詢信息
OFFSET=0 and LIMIT=5 只會記錄五次信息
OFFSET≥0的時候,內存中只會記錄LIMIT調跟蹤信息
SET optimizer_trace_offset=-5, optimizer_trace_limit=5;
多個語句執行N次N大於5在進行查詢:debug
SELECT * FROM information_schema.OPTIMIZER_TRACE;
能夠看到只是記錄了最後的五條信息而已。
官網給出了建議的查詢語句:
SELECT * FROM OPTIMIZER_TRACE LIMIT LIMIT OFFSET OFFSET ;
並且咱們還能夠經過如下語句監控到使用的內存究竟是多少:3d
show variables like 'optimizer_trace_max_mem_size';
並且OPTIMIZER_TRACE表的MISSING_BYTES_BEYOND_MAX_MEM_SIZE這個列還會記錄到當前語句丟失了多少內存,而咱們經過show variables like 'optimizer_trace_max_mem_size';查找的內存使用信息每每是和真是的偏小一點,真實內存使用每每要高。
OPTIMIZER_TRACE表的INSUFFICIENT_PRIVILEGES是用來查看權限的,當一些複雜的語句,可是查看跟蹤的用戶缺乏權限的時候,這列值每每將顯示爲1。這就表示實際上是沒有權限的。
並且要記住一點就是跟蹤器的事件若是被記錄下來的話,那麼也是會被自動記錄到 --debug file當中的.
咱們知道跟蹤器的話是以JOSN存儲trace的,可是JOSN的格式是很難閱讀的,因此說MySQL有了如下的參數:
end_markers_in_json這個變量:
root@localhost [information_schema]>show variables like 'end_markers_in_json';
+---------------------+-------+
| Variable_name | Value |
+---------------------+-------+
| end_markers_in_json | OFF |
+---------------------+-------+
1 row in set (0.01 sec)
下面設置如下setting @@end_markers_in_json=on;打開參數之後再去查詢的話就會方便的多(這個參數是5.7特有的):code
或者咱們使用EXPLAIN FORMAT=JSON也能夠達到相同的結果。
那麼問題來了,優化跟蹤器有哪些特色呢,跟蹤優化器能夠避免屢次跟蹤同一個語句,這樣就不會形成跟蹤文件的瘋狂增加。跟蹤優化器主要有如下的特色:
懶查詢:這樣的話一個JOIN語句有N個表,最多隻會產生N階乘個執行計劃
動態範圍跟蹤:只輸出檢查範圍內的記錄,範圍內記錄只會從新運行一次,可是沒有運行過的記錄就會從新生成一個計劃。
子查詢:每一個字查詢只會運行一次
這些功能咱們是能夠本身設置的:>show variables like 'optimizer_trace_features';
咱們能夠看一下跟蹤的記錄信息,可能會有點亂:
join-preparation 準備
join-optimization優化對象
join-execution最後執行
以及調用的範圍內優化,成本評估,爲何選擇在另外一個的訪問路徑,爲何仍是選擇了另一個排序方法,顯示過的緣由。距離顯示一切都在發生優化遠,但咱們計劃顯示將來更多的信息。因爲截圖很亂,不知道大家看獲得不,體驗眼力勁的時候出現了。固然也能夠經過前面的方式修改一下格式看一下可能更加的樂觀。
咱們最好將跟蹤記錄而且導出到文件,這樣看起來更加好看
SELECT TRACE FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE into outfile'/var/lib/mysql-files/dump.sql';
若是想要其餘人看不到本身的跟蹤信息,必定要記得打開如下的參數:orm
--maximum-optimizer-trace-max-mem-size=0 --optimizer-trace-max-mem-size=0