type
status
date
slug
summary
tags
category
icon
password

前言:

MySQL5.6 開始新增了 semi-join 優化了 IN (SELECT ... FROM ...),但有相似效果的 EXISTSNOT IN/EXISTS 卻沒有類似的優化,大多時候可能都必須透過其他的方式 (例如: LEFT JOIN) 來達到優化的效果,但從 8.0.168.0.17 大家都能享受到優化,可以更愉快的使用這類語法囉!

實際執行

表結構

EXISTS 優化

8.0.16 中優化了 EXISTS 也可以吃到 INsemi-join 優化!
如上範例,可以注意到 8.0.16EXISTS 語句不只在 EXPLAIN 中出現 semi-joinFirstMatch 優化,而且在 WARNINGS 中的改寫也出現 semi-join,相對的 SUBQUERY也消失了。

NOT IN/EXISTS 優化

8.0.17 中優化了帶有 NOTIN、EXISTS 可以使用 anti-join 的優化
如上範例,可以注意到 8.0.17NOT IN能看到 WARNING 中被改寫為 anti-join,相對的 SUBQUERY也消失了,而且還沒有可怕的 DEPENDENT SUBQUERY,執行時間上當然也有所縮短。

結語:

本次 MySQL 8.0 針對 (NOT) IN|EXISTS 的優化方式個人認為相當的實用,並且 semi(anti)-join 還能夠搭配上 8.0HASH JOIN 相比過去能更大幅度的改善這類語法的效能,也不用像過去為了讓這類語法有更好的效能,用其他手段改寫導致可能犧牲一些可讀性,一舉數得真的很棒呢 😍

延伸閱讀

參考資料