type
status
date
slug
summary
tags
category
icon
password
前言:
MySQL5.6 開始新增了 semi-join 優化了 IN (SELECT ... FROM ...),但有相似效果的 EXISTS 及 NOT IN/EXISTS 卻沒有類似的優化,大多時候可能都必須透過其他的方式 (例如: LEFT JOIN) 來達到優化的效果,但從 8.0.16和 8.0.17 大家都能享受到優化,可以更愉快的使用這類語法囉!實際執行
表結構
EXISTS 優化
8.0.16 中優化了 EXISTS 也可以吃到 IN 的 semi-join 優化!如上範例,可以注意到
8.0.16 的 EXISTS 語句不只在 EXPLAIN 中出現 semi-join 的 FirstMatch 優化,而且在 WARNINGS 中的改寫也出現 semi-join,相對的 SUBQUERY也消失了。NOT IN/EXISTS 優化
8.0.17 中優化了帶有 NOT 的 IN、EXISTS 可以使用 anti-join 的優化如上範例,可以注意到
8.0.17的 NOT IN能看到 WARNING 中被改寫為 anti-join,相對的 SUBQUERY也消失了,而且還沒有可怕的 DEPENDENT SUBQUERY,執行時間上當然也有所縮短。結語:
本次
MySQL 8.0 針對 (NOT) IN|EXISTS 的優化方式個人認為相當的實用,並且 semi(anti)-join 還能夠搭配上 8.0 的HASH JOIN 相比過去能更大幅度的改善這類語法的效能,也不用像過去為了讓這類語法有更好的效能,用其他手段改寫導致可能犧牲一些可讀性,一舉數得真的很棒呢 😍