повышение производительности запросов за счет удаления внутреннего хеш-оператора оператора

9

Пытаясь применить содержание этого вопроса ниже к моей собственной ситуации, я немного сбит с толку, как я мог бы избавиться от оператора Hash Match (Inner Join), если это возможно.

Производительность запросов к SQL Server - устранение необходимости в хешировании (внутреннее объединение)

Я заметил, что стоимость составляет 10%, и мне было интересно, смогу ли я снизить ее. Смотрите план запроса ниже.

введите описание изображения здесь

Эта работа взята из запроса, который мне пришлось настроить сегодня:

SELECT c.AccountCode, MIN(d.CustomerSID) 
FROM   Stage.Customer c 
INNER JOIN Dimensions.Customer d  ON c.Email = d.Email
                                  OR (
                                          c.HomePostCode = d.HomePostCode
                                       AND c.StrSurname = d.strSurname
                                                                    )
GROUP BY c.AccountCode

и после добавления этих индексов:

---------------------------------------------------------------------
-- Create the indexes
---------------------------------------------------------------------

CREATE NONCLUSTERED INDEX IDX_Stage_Customer_HOME_SURNAME_INCL
ON Stage.Customer(HomePostCode ,strSurname)
INCLUDE (AccountCode)
--WHERE HASEMAIL = 0
--WITH (ONLINE=ON, DROP_EXISTING = ON)
go


CREATE NONCLUSTERED INDEX IDX_Dimensions_Customer_HOME_SURNAME_INCL
ON Dimensions.Customer(HomePostCode ,strSurname)
INCLUDE (AccountCode,CustomerSID)
--WHERE HASEMAIL = 0
--WITH (ONLINE=ON, DROP_EXISTING = ON)
go



CREATE NONCLUSTERED INDEX IDX_Stage_Customer_EMAIL_INCL
ON Stage.Customer(EMAIL)
INCLUDE (AccountCode)
--WHERE HASEMAIL = 1
--WITH (ONLINE=ON, DROP_EXISTING = ON)
go


CREATE NONCLUSTERED INDEX IDX_Dimensions_Customer_EMAIL_INCL
ON Dimensions.Customer(EMAIL)
INCLUDE (AccountCode,CustomerSID)
--WHERE HASEMAIL = 1
--WITH (ONLINE=ON, DROP_EXISTING = ON)
go

это новый запрос:

----------------------------------------------------------------------------
-- new query 
----------------------------------------------------------------------------

SELECT * 
FROM (    
SELECT AccountCode
     ,RO=ROW_NUMBER () OVER (PARTITION BY AccountCode ORDER BY CustomerSID)
     --,CustomerSID=MIN(CustomerSID) OVER (PARTITION BY AccountCode ORDER BY AccountCode)
       ,CustomerSID
FROM (    
          SELECT c.AccountCode, D.CustomerSID
       FROM   Stage.Customer c 
       INNER JOIN Dimensions.Customer d  ON c.Email = d.Email

          UNION ALL

          SELECT c.AccountCode, D.CustomerSID
       FROM   Stage.Customer c 
       INNER JOIN Dimensions.Customer d  ON c.HomePostCode = d.HomePostCode
                                        AND c.StrSurname = d.strSurname
) RADHE
) R1
WHERE RO = 1

Это сократило время выполнения запроса с 8 минут до 1 секунды.

Все счастливы, но все же я хотел бы знать, смогу ли я сделать больше, то есть, удалив оператор хеш-поиска.

Почему это там, во-первых, я сопоставляю все поля, почему хэш?

Марчелло Миорелли
источник

Ответы:

14

Следующие ссылки обеспечат хороший источник знаний о планах выполнения.

Из Основы Плана Выполнения - Путаница в Хеш-Матче я нашел:

От http://sqlinthewild.co.za/index.php/2007/12/30/execution-plan-operations-joins/

«Хеш-соединение является одной из более дорогих операций соединения, так как для этого требуется создание хеш-таблицы. При этом это соединение лучше всего подходит для больших несортированных входных данных. Оно наиболее интенсивно использует память из всех из соединений

Хеш-соединение сначала считывает один из входных данных и хэширует столбец соединения и помещает полученный хеш-код и значения столбца в хеш-таблицу, созданную в памяти. Затем он читает все строки во втором входном файле, хэширует их и проверяет строки в результирующем хэш-контейнере на наличие соединяющихся строк. "

какие ссылки на этот пост:

http://blogs.msdn.com/b/craigfr/archive/2006/08/10/687630.aspx

Можете ли вы объяснить этот план выполнения? дает хорошее представление о плане выполнения, не относящееся к хэш-соответствию, но актуальное.

Постоянное сканирование - это способ для SQL Server создать сегмент, в который он будет помещать что-то позднее в план выполнения. Я разместил более подробное объяснение этого здесь . Чтобы понять, для чего нужно постоянное сканирование, вам нужно заглянуть в план. В данном случае это операторы Compute Scalar, которые используются для заполнения пространства, созданного постоянным сканированием.

Операторы Compute Scalar загружаются с NULL и значением 1045876, поэтому они явно будут использоваться с Loop Join для фильтрации данных.

Действительно крутая часть в том, что этот план тривиален. Это означает, что он прошел минимальный процесс оптимизации. Все операции ведут к интервалу слияния. Это используется для создания минимального набора операторов сравнения для поиска по индексу ( подробности здесь ).

В этом вопросе: Могу ли я заставить SSMS показывать мне фактическую стоимость запроса на панели плана выполнения? Я исправляю проблемы с производительностью хранимой процедуры с несколькими состояниями в SQL Server. Я хочу знать, на какие части я должен тратить время.

Я понимаю, как читать Query Cost, и всегда ли это процент? что даже когда SSMS предписано включить фактический план выполнения, показатели «Стоимость запроса (относительно пакета)» по-прежнему основаны на оценочных значениях, которые могут быть далеки от фактических

Измерение производительности запросов: «Стоимость запроса плана выполнения» и «Время, затраченное на выполнение», дают хорошую информацию, когда вам нужно сравнить производительность двух разных запросов.

В разделе Чтение плана выполнения SQL Server вы можете найти отличные советы по чтению плана выполнения.

Другие вопросы / ответы, которые мне действительно понравились, потому что они имеют отношение к этой теме, и для моей личной ссылки я хотел бы процитировать:

Как оптимизировать T-SQL запрос с использованием плана выполнения

Может ли SQL создать хороший план для этой процедуры?

Планы выполнения отличаются для одного и того же оператора SQL

Марчелло Миорелли
источник