Коммутативность объединений в SQL

Существует несколько обсуждений Stackru коммутативности объединений, таких как 1, 2, 3 и 4. Это становится довольно сложно, и я не думаю, что кто-то из них ответит на мой вопрос здесь.

Я часто замечал, что когда я помещаю SQL для запроса в Access, Access портит порядок моих объединений и даже меняет LEFT присоединяется к RIGHT из них. Я обычно пишу свои внешние соединения как LEFT s, логически выстраивая последовательность объединенных таблиц, поэтому мне не нравится, когда Access портит это. Но теперь я заметил разницу в том, как запрос представлен в представлении "Дизайн", и я хочу знать, является ли разница существенной.

Вот три запроса:

Query1

SELECT Table1.ID_Table1
FROM Table2 RIGHT JOIN (Table1 LEFT JOIN Table12 
    ON Table1.ID_Table1 = Table12.ID_Table1) ON Table2.ID_Table2 = Table12.ID_Table2;

Query2

SELECT Table1.ID_Table1
FROM Table1 LEFT JOIN (Table2 RIGHT JOIN Table12 
    ON Table2.ID_Table2 = Table12.ID_Table2) ON Table1.ID_Table1 = Table12.ID_Table1;

Query3

SELECT Table1.ID_Table1
FROM Table1 LEFT JOIN (Table12 LEFT JOIN Table2 
    ON Table12.ID_Table2 = Table2.ID_Table2) ON Table1.ID_Table1 = Table12.ID_Table1;

Я предпочитаю Query3, потому что он имеет логический порядок, который я упомянул.

Когда я ввел эти запросы как SQL, Access изменил код Query2 на тот же, что и Query1, и не изменил код Query1 или Query3. Когда три запроса выполняются (с очень простыми данными, поэтому не являются окончательными), они все дают одинаковый результат. В представлении "Дизайн" Query1 и Query2 выглядят одинаково, что хорошо, поскольку Access преобразовал Query2 в Query1. Query3 выглядит почти так же, за исключением того, что отношения между Table2 и Table12, которые представлены в представлении Query1 и Query2, не представлены в представлении Query3.

Поэтому мой вопрос в том, эквивалентен ли Query3 запросам Query1 и Query2, чтобы можно было игнорировать потерю представления табличных отношений в представлении конструктора или существует ли эксплуатационная разница в запросах? Если есть разница, есть ли руководящий принцип для упорядочения объединений?

1 ответ

Это не ответ, а комментарий, который не помещается в разделе комментариев.

... Доступ путает с порядком моих соединений и даже меняет ЛЕВЫЕ соединения на ПРАВЫЕ...

Дело в том, что SQL является декларативным языком. В отличие от императивных языков, таких как C, C++, Java, PHP и т. Д., Вы не указываете, как получить нужные данные, а вместо этого указываете движку SQL, что вам нужно.

Когда вы запускаете оператор SQL, ядро ​​базы данных будет обрабатывать запрос в несколько "фаз": от синтаксического анализа, кэширования, применения параметров, перефразирования, планирования, оптимизации, выполнения, конвейерной обработки, доставки и т. Д. Каждый механизм базы данных добавит дополнительные фазы к те, которые я упоминаю.

В этом вопросе интересны перефразирование, планирование и оптимизация.

  • Очень часто движок перефразирует SQL, чтобы лучше им управлять. Может быть миллион причин, почему разработчики движка решили, что движок будет лучше управлять планом, если он написан "вверх ногами". Вы не можете реально контролировать это. Иногда есть действительно веские причины, которые вы можете понять; в других случаях это связано с внутренней организацией механизма базы данных.

  • Затем планировщик SQL рассматривает упомянутые вами таблицы, указанные вами условия фильтрации, существующие индексы, статистику таблиц (обновленную или устаревшую) и создает набор планов. Все эти планы дадут действительный результат.

  • Затем этот набор планов передается оптимизатору, который оценит стоимость (затраченное время, дисковый ввод-вывод, потребление памяти, пропускную способность сети и т. Д.) И выберет "лучший", насколько ему известно. Пожалуйста, учтите, что, насколько ему известно, это может быть довольно неубедительным, в зависимости от того, насколько слаб или хорош оптимизатор, и чаще всего выбранный "оптимальный" план может быть не самым лучшим.

Теперь, чтобы быть реалистичным, MS-Access определенно не самый лучший из движков баз данных. Вы можете ожидать, что планировщик SQL и оптимизаторы не являются удивительными. Они выполняют свою работу, но рассчитаны на скромный объем данных, а не миллионы строк.

Итог, не ожидайте, что план выполнения будет точно соответствовать тому, что вы ввели. SQL является декларативным языком, и оптимизатор может свободно переписывать и обрабатывать запрос столько раз, сколько он хочет, для хранения и извлечения данных эффективным и безопасным способом.

Другие вопросы по тегам