| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Составление SQL-запросов > LEFT JOIN быстрей INNER JOIN |
| Автор: Kolovorot 26.6.2012, 16:00 | ||
| Собственно сам вопрос: В каких ситуациях левый джойн может быть быстрей inner join? Update: Сам пример: Sql Sever 2008 Есть две вьюхи Documents(Документы) и Payments(Выплаты по документам), и одна таблица Banks(тот кто выплачивает). Отношения: Documents(1) - Payments(n) Documents(n)-Banks(1). Количество записей, примерно: Payments: 250 тыс Documents: 35 тыс Banks: 8 тыс. Код
выполняется за пятнадцать секунд, а если left заменить на inner, то запрос после десяти минут ожидания приходилось останавливать самому. Documents.BankID может быть пустым. |
| Автор: Akina 26.6.2012, 16:05 |
Вы уж определитесь... |
| Автор: Zloxa 26.6.2012, 16:12 |
| Левый и правый суть одно и то же. inner, как указано в заголовке темы и left, right суть разные вещи. В тех, когда планы запроса для левого и правого отличаются в не выгодную для правого пользу SQL - декларативный язык. Он не определяет то, как результат должен быть получен. Он определяет каким он должен быть. В идеале, два по разному сформулированных запроса, описывающих одну и ту же выборку, на одном и том же наборе данных, с одинаковым значением параметров, должны выполняться одинаково. Если это не так, это обуславливается лишь не совершенством современных оптимизаторов. |
| Автор: Kolovorot 26.6.2012, 16:17 | ||
Ой точно опечатался. Благодарю поправил конечно имел в виду left vs inner. |
| Автор: Zloxa 26.6.2012, 16:24 |
Это разные по сути операции. inner join может быть выражен через left, наоборот - нет. Для случая, когда необходимо получить внешнее соединение, смысла сравнивать нет. Для случая, когда внутреннее эквивалентно внешнему, смысла использовать вншенее - нет. Выполняться же они, по хорошему, в этом случае должны бы одинаково. |
| Автор: Kolovorot 26.6.2012, 16:33 |
| Обновил топик с вопросом |
| Автор: Zloxa 26.6.2012, 16:42 |
Не увидел в топике вопроса. Вам нужно чтобы inner работал с той же скоростью, с какой работает left? Смотрите в план в чем разница. Вероятнее всего выбирается другой порядок объединения таблиц. Как тут реагировать - зависит от платформы. Обновлять статистику, добавлять хинты... Край, закостылиться можно попробовать добавив where bank.id is not null. Результат будет эквивалентен inner join Вью на вью на вью = смерть. |
| Автор: Akina 26.6.2012, 16:46 | ||
DDL в студию. |
| Автор: Zloxa 26.6.2012, 16:57 |
И чо, действительно думаешь мозг поломать над эпическими джойнами во вьюхах? Тогда советую реквестнуть сразу и планы для обоих кейсов |
| Автор: Zloxa 26.6.2012, 17:21 | ||
тут практика - критерий истины. Но объяснение просто. Дано: сложная вью. Сверху сложной вью громоздим другую сложную вью. У оптимизатора два выхода. Использовать первую вью как Inline, второй - раскрыть вью и попытаться их функционал объеденить. В первом случае окажется что выполнено много не нужной работы ибо часть работы, которая делает первая вью, для результата второй, в принципе - не необходима. Результат - не оптимален. Во втором случае, у оптимизатора увеличивается глубина дерева вероятных планов и увеличивается шанс оптимизатору запутаться и выдать не оптимальный план. К сожалению, да, на данном этапе развития оптимизаторов, повторное использование в SQL оказываетя весьма и весьма череватым.
А вот и она - практика |