如何一次查询有限行中的 T-SQL 表

Posted

技术标签:

【中文标题】如何一次查询有限行中的 T-SQL 表【英文标题】:How can I query a T-SQL table in limited rows at a time 【发布时间】:2013-11-20 16:55:34 【问题描述】:

我有一个(例如)1500 行的表。我已经确定(由于服务器的资源)我的查询可以在我想要的查询中快速处理我的表的多达 500 行。一次超过 500 行,它突然变得非常慢。

如何构建查询以处理 500 行组中的表内容,直到表的末尾?

[EDIT]需要很长时间的查询是这样的:

select p.childid, max(c.childtime) ChildTime
from child c
    inner join @parents p on p.parentid = c.parentid
        and c.ChildTypeID = 1
    AND c.childtime < getdate()
group by p.parentid

问题是point 表有数百万行并且(由于我无法进入这里的原因)无法减少。

主要问题是:减少子表的行数以提高查询的性能。不幸的是,执行此查询是为了填充一个临时表,以便后续查询可以快速执行。

【问题讨论】:

在选择查询中使用前 500 名? 我会考虑修复导致您的查询运行缓慢的任何问题,而不是试图规避问题。 1500 行绝对算不上什么,无论你有什么查询都应该运行得足够快。 它被加入到一个相当大的查询中,其中包含 MAX() 和其他各种东西。执行计划显示没有太多可以改进的地方,tbh。 TOP 500 无济于事,因为它不会处理剩余的行。我只想一次处理 500 个,直到表格结束。这肯定是可能的,不是吗? 你说的是哪种处理方式? 取决于您的数据。基本上你想要分页。例如 page_start 和 page_start + 499 之间的 line_number 之类的东西。下次通过 page_start 是最后一个,页面结束。 【参考方案1】:

一种可能性是使用窗口函数。唯一的技巧是它们不能在 WHERE 子句中使用,因此您必须使用子查询。

Select a.*, b.*
From 
 (
  Select *, rownum = ROW_NUMBER() over (order by fieldx)
  From TableA
  ) a
  Inner Join TableB b on a.fieldx=b.fieldx
Where a.rownum between @startnum and @endnum

【讨论】:

【参考方案2】:

如果这只是为了处理,你也许可以这样做:

DECLARE @RowsPerPage INT = 500, @PageNumber INT = 1
DECLARE @TotalRows INT

SET @TotalRows = (SELECT count(1) from test)

WHILE (@RowsPerPage * @PageNumber < @TotalRows)
BEGIN

    SELECT
        Id
    FROM 
        (
            SELECT
                Id,
                ROW_NUMBER() OVER (ORDER BY Id) as RowNum
            FROM Test
        ) AS sub
    WHERE sub.RowNum BETWEEN ((@PageNumber-1)*@RowsPerPage)+1
        AND @RowsPerPage*(@PageNumber)

    SET @PageNumber = @PageNumber + 1

END

计算总行数,然后循环遍历结果。但是,如果您需要将结果放在一起,这并没有太大帮助,因为这将运行 X 个单独的查询。您也许可以将它放在一个存储过程中,然后合并结果或类似的疯狂的东西,以便在一个“查询”中获得结果。

我仍然认为更好的选择是解决原始查询中的缓慢问题。是否可以将连接结果加载到 CTE/Temp 表中以仅执行一次计算?如果您可以举一个查询示例,这将有很大帮助...

【讨论】:

以上是关于如何一次查询有限行中的 T-SQL 表的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Update 语句添加到我将要插入到带有 MS SQL 查询的表中的选定行中?

T-SQL:如何在值列表中选择不在表中的值?

如何从 T-SQL 中的表中选择前 N 行?

T-SQL::join sys.masked_columns 返回表中的所有列

T-SQL 查询将数据插入到具有可变列数的表中

如何在 T-SQL 查询中针对连接到 SAP-HANA 的链接服务器使用“占位符”?