Операторы плана запроса, которые скрывают работу
Пересказ статьи Erik Darling. Query Plan Operators That Hide Work
При чтении планов запросов вы можете столкнуться с огромным количеством информации, часть которой может помочь лишь косвенно.
Иногда, когда я объясняю планы запросов людям, я чувствую себя механиком, который просто знает то место, где двигатель производит конкретное дребезжание.
Это не самая плохая вещь. Если вы знаете, что делать, когда услышите погромыхивание в следующий раз, вы чему-то научились.
Один конкретный источник неприятного дребезжания представляется операторами плана запроса, которые выполняют много чего.
Я хочу поговорить о моем любимом примере, поскольку он может вызвать большую путаницу и может спрятать много работы, которая выполняется за спиной маленького и вроде бы дружественного оператора.
Следует иметь в виду, что я смотрю фактические планы. Если вы смотрите на предварительные/кешированные планы, информация, которую вы получите, может оказаться неточной или быть точной только для закешированной версии плана. Повторно используемый план запроса с параметрами, которые требуют отличного количества работы, могут давать совершенно другие числа.
Давайте посмотрим на пример поиска ключа (key lookup), поскольку его легко использовать.
Вы подумали, судя по "loops" в названии, что увидите некоторое количество выполнения оператора, равное количеству циклов, которое, по мнению SQL Server, будет сделано.
Но нет, мы не увидим этого.
В параллельном плане вы можете увидеть число выполнений, равное числу потоков, которое использует запрос для ветви, в которой выполняется соединение вложенными циклами.
Например, вышеприведенный запрос выполняется при MAXDOP четыре, и соответственно использует четыре потока для параллельного соединения вложенными циклами. Это связано с тем, что при параллельных вложенных циклах каждый поток выполняет независимо последовательную версию соединения. С такими вещами, как параллельное сканирование, потоки работают более согласованно.
Слишком много скорости
Если мы снова запустим тот же самый запрос с MAXDOP 1, число выполнений упадет до 1 для оператора nested loops, но останется 71048 для поиска ключа.
Ну вот мы и пришли! Именно дочерние операторы соединения вложенными циклами показывают, сколько было выполнений, а не сами вложенные циклы.
Странно, правда?
Один конкретный источник неприятного дребезжания представляется операторами плана запроса, которые выполняют много чего.
Я хочу поговорить о моем любимом примере, поскольку он может вызвать большую путаницу и может спрятать много работы, которая выполняется за спиной маленького и вроде бы дружественного оператора.
Следует иметь в виду, что я смотрю фактические планы. Если вы смотрите на предварительные/кешированные планы, информация, которую вы получите, может оказаться неточной или быть точной только для закешированной версии плана. Повторно используемый план запроса с параметрами, которые требуют отличного количества работы, могут давать совершенно другие числа.
Nested Loops (вложенные циклы)
Давайте посмотрим на пример поиска ключа (key lookup), поскольку его легко использовать.
CREATE INDEX ix_whatever ON dbo.Votes(VoteTypeId);
SELECT v.VoteTypeId, v.BountyAmount
FROM dbo.Votes AS v
WHERE v.VoteTypeId = 8
AND v.BountyAmount = 100;
Вы подумали, судя по "loops" в названии, что увидите некоторое количество выполнения оператора, равное количеству циклов, которое, по мнению SQL Server, будет сделано.
Но нет, мы не увидим этого.
В параллельном плане вы можете увидеть число выполнений, равное числу потоков, которое использует запрос для ветви, в которой выполняется соединение вложенными циклами.
Например, вышеприведенный запрос выполняется при MAXDOP четыре, и соответственно использует четыре потока для параллельного соединения вложенными циклами. Это связано с тем, что при параллельных вложенных циклах каждый поток выполняет независимо последовательную версию соединения. С такими вещами, как параллельное сканирование, потоки работают более согласованно.
Слишком много скорости
Если мы снова запустим тот же самый запрос с MAXDOP 1, число выполнений упадет до 1 для оператора nested loops, но останется 71048 для поиска ключа.
Ну вот мы и пришли! Именно дочерние операторы соединения вложенными циклами показывают, сколько было выполнений, а не сами вложенные циклы.
Странно, правда?
Обратные ссылки
Автор не разрешил комментировать эту запись
Комментарии
Показывать комментарии Как список | Древовидной структурой