Оконная функция SQL Server с условиями (условие where для инкрементальной загрузки)

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

Самая простая часть - извлечь данные напрямую.

SELECT  s.*
FROM    dbo.source_table s
WHERE   s.load_datetime > ( SELECT  ISNULL(MAX(t.load_datetime) , '0001-01-01')
                                FROM    dbo.target_table AS t
                          )

План запроса очень быстрый и просто определяет дельту.

Если я хочу удалить дубликаты, я добавил DENSE_RANK.

SELECT  *
FROM    ( SELECT  s.*
                 ,DENSE_RANK() OVER ( PARTITION BY s.business_key ORDER BY s.load_datetime ) AS row_no
          FROM    dbo.source_table s
          WHERE   s.load_datetime > ( SELECT  ISNULL(MAX(t.load_datetime) , '0001-01-01')
                                      FROM    dbo.target_table AS t
                                    )
        ) AS sub
WHERE   sub.row_no = 1

Проблема в том, что SQL Server всегда выполняет оконную функцию, прежде чем он выполняет фильтрацию в load_datetime. Я изменил запрос во всех различных формах и исследовал сеть для решения. Я попробовал это также с CROSS APPLY и CTE:

WITH  data
        AS ( SELECT s.*
             FROM   dbo.source_table s
             WHERE  s.load_datetime > ( SELECT  ISNULL(MAX(t.load_datetime) , '0001-01-01')
                                        FROM    dbo.target_table AS t
                                      )
           )
     SELECT *
     FROM   ( SELECT  *
                     ,DENSE_RANK() OVER ( PARTITION BY business_key ORDER BY load_datetime ) AS row_no
              FROM    data
            ) AS sub
     WHERE  sub.row_no = 1

Тем не менее сортировка всей таблицы хх строк Mio вместо дельты.

У кого-нибудь есть идея, как получить только первую строку подзапроса без оконной функции для расчета всего набора данных? Это должен быть SELECT или VIEW без временной таблицы.

Это текущие планы: http://brentozar.com/pastetheplan/?id=Sy2IFSjKg (самая быстрая, без повторной проверки) http://brentozar.com/pastetheplan/?id=BJJpKSstl(сортировка всех 50 миллионов строк) http://brentozar.com/pastetheplan/?id=Byre5BoFe (cte же)

Я попытался удалить индекс хранилища столбцов и создать полезные некластеризованные индексы. Нет эффекта. Все еще делает плотный ранг перед предложением where.

0 ответов

Другие вопросы по тегам