背 景
MySQL引入了Materialization(物化)這一關鍵特性用于子查詢(比如在IN/NOTIN子查詢以及 FROM子查詢)優(yōu)化,其關鍵點在于對子查詢只需要執(zhí)行一次。具體實現(xiàn)方式為:
在SQL執(zhí)行過程中,第一次需要子查詢結果時執(zhí)行子查詢并將子查詢的結果保存為臨時表。
后續(xù)對子查詢結果集的訪問將直接通過臨時表獲得。
與之相對的執(zhí)行方式是對外表的每一行都對子查詢進行調(diào)用,其執(zhí)行計劃中的查詢類型為“DEPENDENTSUBQUERY”。雖然物化子查詢有利于提高SQL的執(zhí)行效率,但如果使用不當,會引起意想不到的后果,比如數(shù)據(jù)庫宕機,今天所講的案例就是這樣一個場景。
案例分析
一MySQL-5.7.17測試環(huán)境,業(yè)務發(fā)出一條查詢sql語句后,直接引起數(shù)據(jù)庫的宕機,查看err日志,發(fā)現(xiàn)sql語句如下:
問題sql為包括兩個子查詢的多表關聯(lián)select語句。
分析執(zhí)行計劃
執(zhí)行計劃相對簡單,值得注意的是select_type為“SUBQUERY”,它表明該sql可能使用了物化子查詢功能,為了得到確切的信息,查看warning信息:
當包含“materialize”和”materialized-subquery“時,已表明該sql語句使用了物化子查詢。為了看清物化子查詢是如何使用的,格式化上述信息如下:
該sql語句被MySQL進行了重寫,并且兩個子查詢都使用了物化子查詢進行了優(yōu)化,分配兩個臨時表用于存放子查詢的結果,并且為每個臨時表創(chuàng)建hashindex,用于關聯(lián)其它表時,提高效率。
查看optimizer_switch參數(shù)
“materialization=on”表明啟用物化子查詢功能,”derived_merge=on”表明改寫sql,將子查詢合并至外部語句。難道是物化子查詢這個功能引起的嗎?
關閉物化子查詢功能
重新發(fā)起上述sql語句
執(zhí)行計劃表明,該sql語句沒再使用物化子查詢功能
該sql語句執(zhí)行成功,而且數(shù)據(jù)庫也并沒有宕機,看起來真的是物化子查詢這個功能的原因。
查看文檔
在查看5.7.23的變更文檔中發(fā)現(xiàn)如下這個bug
上述bug說明,物化子查詢可能會導致mysql服務宕機,5.7.23及以上版本修復了該問題,運行這樣的sql語句將會報錯,而不會再導致mysql宕機。
測試
為了驗證這個bug,將上述sql語句運行于5.7.23版本中
5.7.23版本中確實產(chǎn)生了錯誤,并且要求關閉物化子查詢功能。
總結
啟用物化子查詢功能,可以提升包含子查詢sql的執(zhí)行效率,但也會觸發(fā)一些潛在問題,如上述的導致MySQL宕機bug,雖通過升級MySQL至5.7.23或最新版本,可以避免該問題;或閉關物化子查詢功能,使sql回退至原始的”DEPENDENT SUBQUERY“執(zhí)行方式,但相應的sql執(zhí)行效率也會下降很多,特別是外層結果特別巨大時。所以在生產(chǎn)環(huán)境,避免子查詢的使用,才是解決該問題的王道。
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/130175.html
摘要:最近的互聯(lián)網(wǎng)線上事故發(fā)生比較頻繁,年月號順豐發(fā)生了一起線上刪庫事件,在這里就不介紹了。最后的最后,線上操作的任何一條命令,再小心也不為過,因為由于你的一個符號而引起的事故可能是你所承擔不起的。 摘要: 使用 Redis 的開發(fā)者必看,吸取教訓啊! 原文:Redis 的 KEYS 命令引起 RDS 數(shù)據(jù)庫雪崩,RDS 發(fā)生兩次宕機,造成幾百萬的資金損失 作者:陳浩翔 Fundebu...
摘要:最近的互聯(lián)網(wǎng)線上事故發(fā)生比較頻繁,年月號順豐發(fā)生了一起線上刪庫事件,在這里就不介紹了。最后的最后,線上操作的任何一條命令,再小心也不為過,因為由于你的一個符號而引起的事故可能是你所承擔不起的。 摘要: 使用 Redis 的開發(fā)者必看,吸取教訓??! 原文:Redis 的 KEYS 命令引起 RDS 數(shù)據(jù)庫雪崩,RDS 發(fā)生兩次宕機,造成幾百萬的資金損失 作者:陳浩翔 Fundebu...
摘要:與大數(shù)據(jù)體系交互上報運行統(tǒng)計數(shù)據(jù)自帶了運行結果的統(tǒng)計數(shù)據(jù),我們希望把這些統(tǒng)計數(shù)據(jù)上報到元數(shù)據(jù)系統(tǒng),作為的過程元數(shù)據(jù)存儲下來。基于我們的開發(fā)策略,不要把有贊元數(shù)據(jù)系統(tǒng)的嵌入源碼,而是在之外獲取,截取出打印的統(tǒng)計信息再上報。一、需求 有贊大數(shù)據(jù)技術應用的早期,我們使用 Sqoop 作為數(shù)據(jù)同步工具,滿足了 MySQL 與 Hive 之間數(shù)據(jù)同步的日常開發(fā)需求。 隨著公司業(yè)務發(fā)展,數(shù)據(jù)同步的場景越...
閱讀 1356·2023-01-11 13:20
閱讀 1707·2023-01-11 13:20
閱讀 1215·2023-01-11 13:20
閱讀 1906·2023-01-11 13:20
閱讀 4165·2023-01-11 13:20
閱讀 2757·2023-01-11 13:20
閱讀 1402·2023-01-11 13:20
閱讀 3671·2023-01-11 13:20