Физическая операция конкатенации: гарантирует ли она порядок выполнения?


12

В стандартном SQL результат a union allне гарантируется в любом порядке. Итак, что-то вроде:

select 'A' as c union all select 'B'

Может вернуть две строки в любом порядке (хотя на практике в любой известной мне базе данных «A» будет стоять перед «B»).

В SQL Server это превращается в план выполнения с использованием физической операции «конкатенации».

Я мог легко предположить, что операция конкатенации будет сканировать свои входные данные, возвращая любой входной файл, имеющий доступные записи. Тем не менее, я нашел следующее заявление в Интернете ( здесь ):

Обработчик запросов выполнит этот план в том порядке, в котором операторы указаны в плане, первый - верхний, а последний - конечный.

Вопрос: это правда на практике? Это гарантировано, чтобы быть правдой?

Я не нашел никаких ссылок в документации Microsoft на то, что входы сканируются по порядку, от первого до последнего. С другой стороны, всякий раз, когда я пытаюсь запустить его, результаты показывают, что входные данные действительно обрабатываются по порядку.

Есть ли способ, чтобы двигатель обрабатывал более одного входа одновременно? Мои тесты (с использованием гораздо более сложных выражений, чем констант) выполняются на 8-ядерном компьютере с параллельной поддержкой, и большинство запросов используют преимущества параллелизма.

Ответы:


10

Нет , от Microsoft нет документации, гарантирующей поведение, поэтому это не гарантируется .

Кроме того, если предположить, что статья Simple Talk верна, и что физический оператор конкатенации всегда обрабатывает входные данные в порядке, указанном в плане (очень вероятно, что это правда), то без гарантии того, что SQL Server всегда будет генерировать планы с одинаковыми порядок между текстом запроса и планом запроса, вам только немного лучше.

Мы можем исследовать это дальше, хотя. Если оптимизатору запросов удалось изменить порядок ввода оператора конкатенации, в недокументированном DMV должны существовать строки, sys.dm_exec_query_transformation_statsсоответствующие этой оптимизации.

SELECT * FROM sys.dm_exec_query_transformation_stats 
    WHERE name LIKE '%CON%' OR name LIKE '%UNIA%'

В SQL Server 2012 Enterprise Edition это создает 24 строки. Игнорирование ложных совпадений для преобразований, связанных с константами, есть одно преобразование, связанное с физическим оператором конкатенации UNIAtoCON(объединение всех в конкатенацию). Таким образом, на уровне физического оператора создается впечатление, что после выбора оператора конкатенации он будет обрабатываться в порядке логического оператора объединения всех, из которого он был получен.


На самом деле это не совсем так. Существуют переоптимизационные переписки, которые могут переупорядочить входные данные для оператора физической конкатенации после завершения оптимизации на основе затрат. Один пример имеет место, когда объединение подчиняется цели строки (поэтому может быть важно сначала прочитать из более дешевого ввода). См. UNION ALLОптимизацию Пола Уайта для более подробной информации.

Это позднее физическое переписывание было функциональным вплоть до SQL Server 2008 R2 включительно, но регрессия означала, что оно больше не применяется к SQL Server 2012 и более поздним версиям. Выпущено исправление, которое восстанавливает это переписывание для SQL Server 2014 и более поздних версий (не 2012) с включенными исправлениями оптимизатора запросов (например, флаг трассировки 4199).


А про оператора логического союза все ( UNIA)? Существует UNIAReorderInputsпреобразование, которое может изменить порядок входов. Есть также два физических оператора, которые можно использовать для реализации логического объединения всех UNIAtoCONи UNIAtoMERGE(объединения всех в объединение).

Поэтому кажется, что оптимизатор запросов может переупорядочить входные данные для a UNION ALL; однако, это, кажется, не является обычным преобразованием (нулевое использование UNIAReorderInputsна серверах SQL, которые у меня легко доступны. Мы не знаем обстоятельств, которые могли бы использовать оптимизатор UNIAReorderInputs; хотя это, безусловно, используется при планировании или использовании Подсказка плана используется для форсирования плана, созданного с использованием физических переупорядоченных входов цели строки, указанных выше.

Есть ли способ, чтобы двигатель обрабатывал более одного входа одновременно?

Физический оператор конкатенации может существовать в параллельном разделе плана. С некоторыми трудностями мне удалось создать план с параллельными объединениями, используя следующий запрос:

SELECT userid, regdate  FROM (  --Users table is around 3mil rows
    SELECT  userid, RegDate FROM users WHERE userid > 1000000
    UNION 
    SELECT  userid, RegDate FROM users WHERE userid < 1000000
    UNION all
    SELECT userid, RegDate FROM users WHERE userid < 2000000
    ) d ORDER BY RegDate OPTION (RECOMPILE)

Таким образом, в самом строгом смысле, физический оператор конкатенации, кажется, всегда обрабатывает входные данные согласованным образом (верхний первый, нижний второй); однако оптимизатор может переключать порядок входов перед выбором физического оператора или использовать объединение слияния вместо конкатенации.


8

По словам Крейга Фридмана, порядок выполнения для оператора конкатенации гарантирован.

Из его блога Просмотр планов запросов в блогах MSDN:

Обратите внимание, что, когда оператор имеет более одного дочернего элемента, порядок дочерних элементов имеет значение. Самый верхний ребенок - первый, а самый нижний - второй. Оператор конкатенации обрабатывает дочерние элементы в этом порядке.

А из книг онлайн Showplan Справочник логических и физических операторов

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


Эта цитата довольно близка к тому, что я искал. Я готов сделать скачок от выполнения в этом порядке до возврата в этом порядке - хотя разочаровывает, что документация исключает параллельную обработку в этом случае.
Гордон Линофф

2

Ответ сообщества вики :

Я не знаю, можете ли вы доказать, что любое наблюдаемое поведение всегда гарантировано, так или иначе, если только вы не можете выдвинуть контрпример. В отсутствие этого, конечно, можно исправить порядок, в котором возвращаются результаты ORDER BY.

Я не знаю, есть ли «исправление» или существует необходимость в исправлении, если вы можете продемонстрировать, что в некоторых сценариях запросы обрабатываются в другом порядке.

Отсутствие какой-либо явной официальной документации подсказывает мне, что вы не должны зависеть от этого. Это как раз то, с чем люди сталкивались с проблемами ORDER BYв представлении, и GROUP BYбез него ORDER BY, 8 лет назад, когда был выпущен оптимизатор SQL Server 2005.

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

Даже если вы не зависите от этого поведения, что вы собираетесь делать с результатами? В любом случае, я не назвал бы статью Simple Talk посторонним чиновником . Насколько мы знаем, это всего лишь предположение, основанное на наблюдении.

Microsoft никогда не собирается публиковать официальную документацию, в которой говорится, что «х» не гарантирует «у». Это одна из причин, по которой у нас все еще, почти десятилетие спустя, возникают проблемы с тем, чтобы убедить людей в том, что они не могут полагаться на наблюдаемый заказ без ORDER BY- нет документации, в которой говорится, что «это не гарантировано».

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.