Sql server 带条件的SQL Server窗口函数(用于增量加载的where子句)

Sql server 带条件的SQL Server窗口函数(用于增量加载的where子句),sql-server,window-functions,row-number,dense-rank,Sql Server,Window Functions,Row Number,Dense Rank,我们希望以增量方式将数据从一个表加载到另一个表。有可能会有重复的。实际上,它应该非常简单,但随着数据的增加,速度会变慢 最简单的部分是直接提取数据 SELECT s.* FROM dbo.source_table s WHERE s.load_datetime > ( SELECT ISNULL(MAX(t.load_datetime) , '0001-01-01') FROM dbo.target_tab

我们希望以增量方式将数据从一个表加载到另一个表。有可能会有重复的。实际上,它应该非常简单,但随着数据的增加,速度会变慢

最简单的部分是直接提取数据

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  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\u datetime进行筛选之前先执行窗口函数。我改变了所有不同形式的查询,并研究了web以寻求解决方案。我还尝试了交叉应用和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
仍然对整个表中的xx mio行进行排序,而不是对增量进行排序

有人知道如何只获取子查询的第一行,而不使用窗口函数来计算整个数据集吗?它需要是没有临时表的SELECT或VIEW


这些是当前的计划:(最快,无重复检查)(对所有5000万行进行排序)(cte相同)


我尝试删除列存储索引并创建有用的非聚集索引。没有效果。仍然在where子句之前进行密集排序

使用这些是当前计划共享您的执行计划:(最快,无重复检查)(对所有5000万行进行排序)(cte相同)执行计划说这是列存储表,我会更新您的标题和问题以包含该信息。@EckhardZemp Dense_Rank将为相同的编号分配相同的排序值。您可能会得到多个子行_no=1。您应该使用行数,而不是密集列。对于Row_Number,即使排序键匹配,分区中的每一行都会得到一个唯一的数字。@SqlZim我刚刚删除了列存储索引,并创建了有用的非聚集索引。没有效果。仍然在where子句之前进行密集排序。韦斯:我两个都试过了。我们的目标是只在增量数据上执行windows功能,而不是在完整数据上。使用这些共享您的执行计划是当前计划:(最快,无重复检查)(对所有5000万行进行排序)(cte相同)执行计划说这是列存储表,我将更新您的标题和问题,以包含该信息。@EckhardZemp\u Rank将为相同的编号分配相同的排序值。您可能会得到多个子行_no=1。您应该使用行数,而不是密集列。对于Row_Number,即使排序键匹配,分区中的每一行都会得到一个唯一的数字。@SqlZim我刚刚删除了列存储索引,并创建了有用的非聚集索引。没有效果。仍然在where子句之前进行密集排序。韦斯:我两个都试过了。目标是只对增量数据执行windows功能,而不是对完整数据执行windows功能。