天天看點

MySQL優化案例:半連接配接(semi join)優化方式導緻的查詢性能低下

MySQL優化案例:半連接配接(semi join)優化方式導緻的查詢性能低下

以下是來自dba+社群mysql領域原創專家李海翔分享的mysql優化案例,關于mysql v5.6.x/5.7.x sql查詢性能問題。

專家簡介

MySQL優化案例:半連接配接(semi join)優化方式導緻的查詢性能低下

李海翔

網名:那海藍藍

dba+社群mysql領域原創專家

從事資料庫研發、資料庫測試與技術管理等工作10餘年,對資料庫的核心有深入研究,擅長于postgresql和mysql等開源資料庫的核心與架構。現任職于oracle公司mysql全球開發團隊,從事查詢優化技術的研究和mysql查詢優化器的開發工作。著有《資料庫查詢優化器的藝術》一書。

一、簡單建立一表,并使用存儲過程插入一部分資料

MySQL優化案例:半連接配接(semi join)優化方式導緻的查詢性能低下

二、執行如下查詢

q1:

MySQL優化案例:半連接配接(semi join)優化方式導緻的查詢性能低下

q2:q2比q1隻多了一個使用or子句連接配接的條件,資料中沒有滿足此條件的資料

MySQL優化案例:半連接配接(semi join)優化方式導緻的查詢性能低下

問題:  q1和q2哪個查詢快?快者比慢者能快出幾倍?為什麼?

三、實際運作結果

對q1和q2稍加改造,目的是避免有大量的查詢結果輸出。目标列使用count()函數替換。

MySQL優化案例:半連接配接(semi join)優化方式導緻的查詢性能低下

看紅色字型,所耗費的時間,q1是q2的近乎40倍。為什麼?

四、探索原因

第一招:察看執行計劃

MySQL優化案例:半連接配接(semi join)優化方式導緻的查詢性能低下

對比執行計劃,發現q1使用了“materialized”物化方式存儲子查詢的臨時結果,是不是物化導緻了q1慢呢?

第二招:察看io

MySQL優化案例:半連接配接(semi join)優化方式導緻的查詢性能低下
MySQL優化案例:半連接配接(semi join)優化方式導緻的查詢性能低下
MySQL優化案例:半連接配接(semi join)優化方式導緻的查詢性能低下

q2和q1不一緻之處在于q2的“handler_read_key”值20002遠遠比比q1的2高,這說明q2更多地利用了索引。

且看mysql官方解釋如下:

handler_read_key

the number of requests to read a row based on a key. if this value is high, it is a good indication that your tables are properly indexed for your queries.

問題:

為什麼q2會有更多的索引讀?索引是從哪裡來的?

q1被物化,意味着q1使用了臨時表;而q2子查詢是否被物化是否使用了臨時表呢?

五、新的疑問,再次探索

之下如下操作,注意show warnings技巧的使用。查詢結果作了形式的調整,便于閱讀。

MySQL優化案例:半連接配接(semi join)優化方式導緻的查詢性能低下

可以看出,q1的子查詢被物化後,又作了半連接配接優化,意味着子查詢被上拉方式優化。

MySQL優化案例:半連接配接(semi join)優化方式導緻的查詢性能低下
MySQL優化案例:半連接配接(semi join)優化方式導緻的查詢性能低下

q2表明,首先使用了臨時表,但是和q1不同的是,子查詢沒有被上拉優化。

但是,mysql對于臨時表的使用,會自動建立索引,是以我們能看到在“auto_key”上執行了“primary_index_lookup”。這就是q2快于q1的原因。也是為什麼q2的索引讀計數器的值較大的原因。

問題:半連接配接優化

六、繼續探索

MySQL優化案例:半連接配接(semi join)優化方式導緻的查詢性能低下

執行計劃似乎改變不大,但類似了q2的執行計劃。(哈哈,可執行show warnings;指令看看,擷取更詳細的資訊才能得出更靠譜的結論)

MySQL優化案例:半連接配接(semi join)優化方式導緻的查詢性能低下

在禁止了半連接配接操作之後,執行速度一下子坐上了飛機,有了40餘倍的提升。

七、結論

1. q1使用了物化+半連接配接優化,q2是子查詢,但沒有使用半連接配接優化,可見mysql中半連接配接優化的效率未必高。

2. 似乎物化的子查詢用半連接配接上拉,mysql的判斷條件還是存在一點兒問題。

<b></b>

<b>本文來自雲栖社群合作夥伴"dbaplus",原文釋出時間:2015-12-07</b>