多年来,我听到很多人说:
与“ OT EXISTS”显示相比,“ join”运算符更为可取。
为什么?
在MySQL,Oracle,SQL Server而且PostgreSQL,NOT EXISTS是相同的效率甚至效率比LEFT JOIN/ IS NULL。
MySQL
Oracle
SQL Server
PostgreSQL
NOT EXISTS
LEFT JOIN/ IS NULL
似乎“应该对外部查询中的每个记录执行内部查询”(这似乎不利NOT EXISTS,甚至更糟NOT IN,因为后者查询甚至没有关联),但它也可以像所有其他查询都使用适当的anti-join方法进行了优化。
NOT IN
anti-join
在SQL Server实际上,LEFT JOIN / IS NULL可以比低效率NOT EXISTS / NOT IN在内部表未索引或低基数列的情况下。
LEFT JOIN / IS NULL
NOT EXISTS / NOT IN
经常听到MySQL“在处理子查询方面特别糟糕”。
这源于以下事实:MySQL嵌套循环以外,没有其他联接方法的能力,这严重限制了其优化能力。
查询将通过将子查询重写为联接而受益的唯一情况是:
SELECT * FROM big_table WHERE big_table_column IN ( SELECT small_table_column FROM small_table )
small_table不会完全查询中的每个记录big_table:尽管它似乎没有关联,但查询优化器将隐式关联它,实际上将其重写为。EXISTS(index_subquery如果需要small_table_column索引,则用于搜索第一个)
small_table
big_table
EXISTS
index_subquery
small_table_column
但是big_table总是领先的,这使得查询完成big * LOG(small)而不是small * LOG(big)读取。
big * LOG(small)
small * LOG(big)
这可以重写为
SELECT DISTINCT bt.* FROM small_table st JOIN big_table bt ON bt.big_table_column = st.small_table_column
然而,这并不会改善NOT IN(相对IN)在MySQL,NOT EXISTS并且LEFT JOIN / IS NULL几乎是相同的,因为与嵌套循环左表应始终处于领先LEFT JOIN。
IN
LEFT JOIN
您可能需要阅读以下文章: