MySQL, як і всі інші системи, крім SQL Server, здатний оптимізувати LEFT JOIN
/IS NULL
повернути, FALSE
як тільки знайдеться відповідне значення, і це єдина система, яка піклується про документування такої поведінки. […] Оскільки MySQL не в змозі використовувати алгоритми HASH
та MERGE
приєднуватись, єдиний ANTI JOIN
він здатнийNESTED LOOPS ANTI JOIN
[…]
По суті, [ NOT IN
] - це абсолютно той самий план, який LEFT JOIN
/ IS NULL
використовується, незважаючи на те, що ці плани виконуються різними гілками коду, і вони виглядають різними за результатами EXPLAIN
. Насправді алгоритми однакові, а запити виконуються за один і той же час.
[…]
Важко сказати точну причину [падіння продуктивності при використанні NOT EXISTS
] , оскільки це падіння лінійне і, схоже, не залежить від розподілу даних, кількості значень в обох таблицях тощо, доки індекси обох полів індексуються. Оскільки в MySQL є три фрагменти коду, які в основному виконують одну роботу, можливо, що код, який відповідає за це, EXISTS
робить якусь додаткову перевірку, яка потребує додаткового часу.
[…]
MySQL може оптимізувати всі три методи для виконання свого роду NESTED LOOPS ANTI JOIN
. […] Однак ці три методи генерують три різні плани, які виконуються трьома різними фрагментами коду. Код, який виконує EXISTS
предикат, приблизно на 30% менш ефективний […]
Ось чому найкращим способом пошуку пропущених значень у MySQL є використання LEFT JOIN
/ IS NULL
або, NOT IN
а не NOT EXISTS
.
(акценти додані)