天天看點

mysql索引無效且sending data耗時巨大原因分析

  一朋友最近新上線一個項目,本地測試環境跑得好好的,部署到線上卻慢得像蝸牛一樣。後來查詢了一下發現一個sql執行了16秒,有些長的甚至80秒。本地運作都是毫秒級别的查詢。下面記錄一下困擾了兩天的,其中一條sql的優化。

  表結構及現象描述:

  表wp_goods資料量10094,sys_users資料量14044, jd_jianding資料量9142。

  執行sql:

  耗時16秒,而本地資料庫執行耗時0.02毫秒。

  原因分析:

  1、explain/desc 發現left join索引不起作用。

  分析結果:

mysql索引無效且sending data耗時巨大原因分析

  索引無效,Using join buffer (Block Nested Loop)相當于周遊表查詢。

  2、profile分析了下,發現幾乎所有耗時都在sending data且緩存sending cached result to clien沒開啟。

  show variables like '%cache%';

  query_cache_type為off,在配置檔案/etc/my.cf中添加“query_cache_type = 1”配置項并重新開機。

  執行後耗時10s,如果将order by去掉後耗時3秒。即使是耗時3秒也是無法接受的。

  通過profile分析下具體耗時

  

mysql索引無效且sending data耗時巨大原因分析

  發現幾乎所有耗時都在sending data部分。

  3、檢視jd_jianding表索引,show index from jd_jianding發現cardinality的值為1。

mysql索引無效且sending data耗時巨大原因分析

  4、優化表jd_jianding,analyze table jd_jianding,再次執行仍然如此。

  然而mysql的文檔時這麼說的。The higher the cardinality, the greater the chance that MySQL uses the index when doing joins. 

  An estimate of the number of unique values in the index. This is updated by running ANALYZE TABLE or myisamchk -a. Cardinality is counted based on statistics stored as integers, so the value is not necessarily exact even for small tables. The higher the cardinality, the greater the chance that MySQL uses the index when doing

  大意如下:

  5、檢視表jd_jianding字段wid的值全為預設值0,于是将其中一條記錄的wid字段值update為非0;再次analyze table jd_jianding。

  再次執行,效果杠杠的,耗時隻有0.02毫秒。困擾兩天的問題終于得到了解決。

  6、把步驟4修改的字段值還原回來。

  後記,原因大緻如下: