为以下模式和示例数据
一个应用程序正在按聚集索引顺序以1,000行为一组处理此表中的行。
从以下查询中检索到了前1,000行。
那个集合的最后一行在下面
有没有一种方式可以编写查询,只需查找该复合索引键,并沿着它获取下一个包含1000行的数据块?
到目前为止,我能够获得的最低阅读数是1020,但是这个查询似乎过于复杂。是否有一种更简单而效率更高的方法?也许可以通过一个范围查找来实现所有操作吗?
FWIW: 如果将列A设置为NOT NULL,并使用-1作为标记值,那么等效的执行计划肯定看起来更加简单。 但是计划中的单个寻找运算符 仍然执行两次寻找 ,而不是将其合并为一个连续的范围,逻辑读取量差不多,所以我怀疑也许这已经是最好的了?
CREATE TABLE T
(
A INT NULL,
B INT NOT NULL IDENTITY,
C CHAR(8000) NULL,
UNIQUE CLUSTERED (A, B)
)
INSERT INTO T
(A)
SELECT NULLIF(( ( ROW_NUMBER() OVER (ORDER BY @@SPID) - 1 ) / 1003 ), 0)
FROM master..spt_values
一个应用程序正在按聚集索引顺序以1,000行为一组处理此表中的行。
从以下查询中检索到了前1,000行。
SELECT TOP 1000 *
FROM T
ORDER BY A, B
那个集合的最后一行在下面
+------+------+
| A | B |
+------+------+
| NULL | 1000 |
+------+------+
有没有一种方式可以编写查询,只需查找该复合索引键,并沿着它获取下一个包含1000行的数据块?
/*Pseudo Syntax*/
SELECT TOP 1000 *
FROM T
WHERE (A, B) is_ordered_after (@A, @B)
ORDER BY A, B
到目前为止,我能够获得的最低阅读数是1020,但是这个查询似乎过于复杂。是否有一种更简单而效率更高的方法?也许可以通过一个范围查找来实现所有操作吗?
DECLARE @A INT = NULL, @B INT = 1000
;WITH UnProcessed
AS (SELECT *
FROM T
WHERE ( EXISTS(SELECT A
INTERSECT
SELECT @A)
AND B > @B )
UNION ALL
SELECT *
FROM T
WHERE @A IS NULL AND A IS NOT NULL
UNION ALL
SELECT *
FROM T
WHERE A > @A
)
SELECT TOP 1000 *
FROM UnProcessed
ORDER BY A,
B
FWIW: 如果将列A设置为NOT NULL,并使用-1作为标记值,那么等效的执行计划肯定看起来更加简单。 但是计划中的单个寻找运算符 仍然执行两次寻找 ,而不是将其合并为一个连续的范围,逻辑读取量差不多,所以我怀疑也许这已经是最好的了?