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оптимальное индексирование, если запрос касается относительно небольшой части соответствующей таблицы. Тестирование необходимо.

Пол Уайт говорит, что GoFundMonica
источник
2

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

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

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

user55424
источник