日常排雷:mysql之數據量越小,查詢越慢?


日常排雷:mysql之數據量越小,查詢越慢

同樣的sql ,在不同的數據庫上,執行效率不一致

 

現象:

mysql版本5.7

數據庫引擎 innoDB

 

測試與開發兩個數據庫上,表結構完全一致、索引一致

數據量有稍微不同

 

大致sql類似:select b.code from A as h LEFT JOIN B as b on b.h_id=h.id limit 0,20 ;

實際sql(公司數據隱私):有900行,n張表關聯,子查詢、in、exists 、order by 啥都有 ~~~

 

開發環境數據庫上的數據情況

A表的數據為4w條左右

B表的數據為23條

 

查詢時間0.068秒

 

測試環境數據庫上的數據情況

A表的數據為4w條左右

B表的數據為5條

 

查詢時間15.703秒

 

A表 id 為主鍵索引

B表為 h_id 普通索引

 

EXPLAIN select b.code from A as h LEFT JOIN B as b on b.h_id=h.id limit 0,20 ;

執行一看

"表B數據為5條" 的數據庫,不走索引,使用了Block Nested Loop 算法

 

 

 

"表B數據為23條" 的數據庫,走了索引

 

 

 

 

 

原來數據量小,還會影響查詢速度,使查詢速度變慢 ???

 

 
做為小白的我,立即查了下資料
 
原來是mysql執行分析器搞的鬼,mysql 用的是CBO優化器。優化器分析出來的結果,不走索引成本更低,所以沒有走索引,最終結果出乎意料。
 
 

 

 


為了驗證是否是成本計算產生的問題,對 “B表數據為5條” 的數據庫對應的表 insert 了18條數據,再查詢,立即秒出 0.06秒

 

 

 

 

果然算法才是精髓啊~~

 

那么為啥不走索引會相差這么大,再看下上面提及的 不走索引,直接使用了Block Nested Loop 算法,

不走索引的情況下,會對A表的全表數據進行關聯匹配,之后再進行limit 0,20。-->>那不就是查全表了嗎,數據量一大不害死人。。。。

走索引的情況下,先 limit 0,20的前20條數據,進行關聯匹配,

這就是最終原因吧

 

以后別說,加了索引,查詢怎么還沒快點啊,先看下執行計划再說~~

 

原來走不走索引,不是你說了算,你建了索引,mysql數據庫還不一定就會走,還得經過一次cost計算,擇出最優索引方案,然而這個最優方案不一定是適合所有場景~~

 

 

參考文章:
 
 
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM