SQL Server,为多个表使用UNION ALL然后分页实现

Rob*_*elo 12 sql-server pagination union-all

我还需要有关分页和使用UNION ALL多个表的帮助:

如何在使用UNION ALL并返回特定行数时连接多个表时实现优化的分页...


declare @startRow int
declare @PageCount int

set @startRow = 0
set @PageCount = 20

set rowcount @PageCount

select Row_Number() OVER(Order by col1) as RowNumber, col1, col2
from
(
    select col1, col2 from table1 where datetimeCol between (@dateFrom and @dateTo)
    union all
    select col1, col2 from table2 where datetimeCol between (@dateFrom and @dateTo)
    union all
    select col1, col2 from table3 where datetimeCol between (@dateFrom and @dateTo)
    union all
    select col1, col2 from table4 where datetimeCol between (@dateFrom and @dateTo)
    union all
    select col1, col2 from table5 where datetimeCol between (@dateFrom and @dateTo)
) as tmpTable
where RowNumber > @startRow
Run Code Online (Sandbox Code Playgroud)

表3,4和5具有大量的行(数百万行),其中表1和2可能只有几千行.

如果startRow为"0",我只期望第1行到第20行(来自表1)的数据.我得到了正确的结果,但在剩余的表上有很高的开销,而sql server尝试所有的数据并过滤它....

@dateFrom和@dateTo的间隔时间越长,我的查询速度就越慢,同时尝试从整个结果集中只检索几行

请帮助我如何使用类似的逻辑实现一个简单但更好的方法.:(

Luk*_*der 0

我认为您的特定用例可以从通常被称为“查找方法”的方法中获益匪浅,如本博客文章中所述,而不是应用OFFSET基于经典的分页(请注意,SQL Server 2012 现在本身支持它) 。您的查询将如下所示。

select top 20 col1, col2
from
(
    select col1, col2 from t1 where datetimeCol between (@dateFrom and @dateTo)
    union all
    select col1, col2 from t2 where datetimeCol between (@dateFrom and @dateTo)
    union all
    select col1, col2 from t3 where datetimeCol between (@dateFrom and @dateTo)
    union all
    select col1, col2 from t4 where datetimeCol between (@dateFrom and @dateTo)
    union all
    select col1, col2 from t5 where datetimeCol between (@dateFrom and @dateTo)
) as tmpTable
where (col1 > @lastValueForCol1)
   or (col1 = @lastValueForCol1 and col2 > @lastValueForCol2)
order by col1, col2
Run Code Online (Sandbox Code Playgroud)

@lastValueForCol1@lastValueForCol2是上一页最后一条记录的相应值。这允许您获取“下一页”。如果ORDER BY方向是DESC,则只需使用<即可。如果(col1, col2)不是全局唯一的tmpTable,您可能需要向查询和WHEREandORDER BY子句添加另一列,以避免在页面之间丢失记录。

使用上述方法,如果没有先获取前 40 条记录,则无法立即跳转到第 3 页。但通常情况下,您无论如何都不想跳那么远。相反,您可以获得更快的查询,可能能够在恒定时间内获取数据,具体取决于您的索引。另外,无论底层数据是否发生变化,您的页面都保持“稳定”(例如,在第 1 页上,而在第 4 页上)。

注意,“seek 方法”也称为键集分页

索引

虽然使用“seek 方法”进行分页总是比使用时更快OFFSET,但您仍然应该确保(col1, col2)在每个表中都对其进行了索引!