MySQL資料量大時,delete操作無法命中索引

2021-09-22 16:36:06 字數 2698 閱讀 3268

最近,在脈脈上看到乙個樓主提出的問題:mysql資料量大時,delete操作無法命中索引;並且還附上了相關案例截圖。

最終,樓主通過開啟mysql分析優化器追蹤,定位到是優化器搞的鬼,它覺得花費時間太長。因為我這個是測試資料,究其原因是因為資料傾斜,導致計算出的資料佔比較大、花費時間長。

大家要記住一點,一條sql語句走哪條索引是通過其中的優化器和代價分析兩個部分來決定的。所以,隨著資料的不斷變化,最優解也要跟著變化。因此,就需要dba來不斷的優化sql。

對於查詢情況,其實mysql提供給我們乙個功能來引導優化器更好的優化,那便是mysql的查詢優化提示(query optimizer hints)。比如,想讓sql強制走索引的話,可以使用 force index 或者use index;它們基本相同,不同點:在於就算索引的實際用處不大,force index也得要使用索引。

explain select * from yp_user force index(idx_gender) where gender=1 ;
同樣,你也可以通過ignore index來忽略索引。

explain select * from yp_user ignore index(idx_gender) where gender=1 ;
在我看來,雖然有mysql hints這種好用的工具,但我建議還是不要再生產環境使用,因為當資料量增長時,你壓根兒都不知道這種索引的方式是否還適應於當前的環境,還是得配合dba從索引的結構上去優化。

接下來,我來教大家如何用mysql的trace分析優化器是如何選擇執行計畫的?很重要的手段,建議多實戰一下。

1、什麼是trace?

關於這個問題,我覺得去最好的描述是官方文件。

在mysql 5.6中,mysql優化器增加了乙個新的跟蹤功能。該介面由一組optimizer_trace_***系統變數和information_schema.optimizer_trace表提供,但可能會發生變化。

通俗點,就是通過trace檔案能夠進一步了解為什麼優化器選擇a執行計畫而不選擇b執行計畫,幫助我們更好的理解優化器的行為。

2、如何使用?

還是得看官方文件。

# 檢視優化器跟蹤是否狀態show variables like '%optimizer_trace%';# 開啟tracing (預設是關閉的):set optimizer_trace="enabled=on";# 你的查詢語句select ...;# 查詢trace json檔案select * from information_schema.optimizer_trace;# 當完成後,關閉traceset optimizer_trace="enabled=off";
3、分析trace檔案

根據我本地的乙個例子為例,具體檔案內容如下。

select * from yp_user where gender=1 | ]}

},,,]

}},},]

},]},,

"potential_range_indexes": [,,

],"setup_range_conditions": [

],"group_index_range": ,

"analyzing_range_alternatives":

],"analyzing_roworder_intersect": }}

}]},,

]},"condition_filtering_pct": 100,

"rows_for_plan": 3100,

"cost_for_plan": 717,

"chosen": true}]

},]}},

]}]}

},}]}

通過這個例子,我們可以得到全表掃瞄的代價如下。

"table_scan":
分析結果:全表掃瞄訪問的rows記錄為3100,代價cost計算為719.1。

索引掃瞄的代價如下。

"range_scan_alternatives": [

]

分析結果:這裡看到了通過idx_gender索引過濾時,優化器預估需要返回2731記錄,訪問代價cost為3278.2,大於全表掃瞄代價719.1;因此,優化器傾向於選擇全表掃瞄。

今晚上就熬夜寫到這裡吧。

Mysql分頁,資料量大時limit優化

mysql的優化是非常重要的。其他最常用也最需要優化的就是limit。mysql的limit給分頁帶來了極大的方便,但資料量一大的時候,limit的效能就急劇下降。同樣是取10條資料 select from order limit 10000,10 select from order limit 0...

MySQL資料量大小查詢

找到information schema 資料庫 存放了其他的資料庫的資訊 a 伺服器中登入並進入information schema use information schema b 使用第三方工具找到庫,查詢即可 1 查詢所有資料的大小 示例以mb為單位 select concat round ...

mysql表資料量大時檢視行數和所佔物理空間

近日需要對一張mysql表進行分表,先查一下它目前的資料量,沒多想直接使用了以下sql,id為主鍵,看起來好像沒什麼問題,沒想到由於資料量太大,跑出來結果需要很久很久。select count id from table name 可以從mysql自帶的information schema庫里檢視相...