Outer Apply vs Left Join Performance


37

Я использую SQL SERVER 2008 R2

Я только что натолкнулся на APPLY в SQL и полюбил, как он решает проблемы с запросами во многих случаях,

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

У меня небольшой объем данных в таблицах локальных БД, и после развертывания код должен работать с данными как минимум в 20 раз больше.

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

Может кто-нибудь сказать, как именно работает приложение и как это повлияет на производительность в очень больших данных, если это возможно, некоторые пропорциональные отношения с размером каждой таблицы, например, пропорциональные n1 ^ 1 или n1 ^ 2 ... где n1 - количество строк в таблице 1.

Вот запрос с 2 левым соединением

select EC.*,DPD.* from Table1 eC left join
  (
   select member_id,parent_gid,child_gid,LOB,group_gid,MAX(table2_sid) mdsid from Table2
   group by member_id,parent_gid,child_gid,LOB,group_gid

  ) DPD2 on DPD2.parent_gid = Ec.parent_gid
        AND DPD2.child_gid = EC.child_gid
        AND DPD2.member_id = EC.member_id
        AND DPD2.LOB = EC.default_lob
        AND DPD2.group_gid = EC.group_gid
  left join
  Table2 dpd on dpd.parent_gid = dpd2.parent_gid 
            and dpd.child_gid = dpd2.child_gid
            and dpd.member_id = dpd2.member_id 
            and dpd.group_gid = dpd2.group_gid 
            and dpd.LOB = dpd2.LOB
            and dpd.table2_sid = dpd2.mdsid

Вот запрос с внешним применением

select * from Table1 ec   
OUTER APPLY (
      select top 1 grace_begin_date,retroactive_begin_date,Isretroactive
                    from Table2 DPD 
                    where DPD.parent_gid = Ec.parent_gid
                    AND DPD.child_gid = EC.child_gid
                    AND DPD.member_id = EC.member_id
                    AND DPD.LOB = EC.default_lob
                    AND DPD.group_gid = EC.group_gid
                    order by DPD.table2_sid desc
     ) DPD 

Ответы:


44

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

APPLYявляется коррелированным соединением ( LATERAL JOINв некоторых продуктах и ​​более новых версиях стандарта SQL это называется ). Как и любая логическая конструкция, она не оказывает прямого влияния на производительность. В принципе, мы должны быть в состоянии написать запрос, используя любой логически эквивалентный синтаксис, и оптимизатор преобразует наши входные данные в точно такой же физический план выполнения.

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

Конкретная форма OUTER APPLY ( SELECT TOP ... )наиболее вероятно приведет к коррелированному объединению вложенных циклов в текущих версиях SQL Server, поскольку оптимизатор не содержит логики для преобразования этого шаблона в эквивалентный JOIN. Связанное соединение вложенных циклов может не работать должным образом, если внешний ввод большой, а внутренний ввод неиндексирован, или необходимые страницы еще не находятся в памяти. Кроме того, определенные элементы стоимостной модели оптимизатора означают, что коррелированное соединение вложенных циклов менее вероятно, чем семантически идентичное, JOINдля создания плана параллельного выполнения.

Я был в состоянии сделать тот же запрос с помощью одного левого соединения и row_number ()

Это может или не может быть лучше в общем случае. Вам нужно будет протестировать оба варианта с репрезентативными данными. LEFT JOINИ , ROW_NUMBERбезусловно , имеет потенциал , чтобы быть более эффективными, но это зависит от точной формы плана запроса выбранной. Основные факторы , которые влияют на эффективность такого подхода является наличием индекса для покрытия колонн , необходимых, и для подачи заказа , необходимого для PARTITION BYи ORDER BYположений. Вторым фактором является размер таблицы. Эффективный и хорошо проиндексированный APPLYможет превзойти ROW_NUMBERоптимальное индексирование, если запрос касается относительно небольшой части соответствующей таблицы. Тестирование необходимо.


2

Первый запрос может выполняться параллельно только одним запросом к серверу sql. Он извлекает все записи и выдает выходные данные на основе критериев фильтра.

Но в случае второго он запускается строка за строкой, и для каждой строки таблица 2 будет сканироваться и добавляться к результату.

если ваш внешний запрос имеет меньше записей, чем второй, то лучше (OUTER APPLY). Но если первый запрос может получить больше данных, то вам следует использовать первый.

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