Коммутативность объединений в SQL - PullRequest
0 голосов
/ 23 января 2019

Существует несколько обсуждений StackOverflow коммутативности соединений, таких как 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.

Three queries testing commutativity of SQL joins

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

1 Ответ

0 голосов
/ 23 января 2019

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

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

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

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

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

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

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

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

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

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

...