如何一次查询有限行中的 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 查询的表中的选定行中?