给定一个包含列的表Orders
:
id | revision | insertedAt
1 0 2016-01-01 00:00.000
1 1 2016-01-01 02:00.000
2 0 2016-01-01 02:00.000
id,修订版组合是唯一的。
我如何才能最好地迁移到此:
id | revision | applyFrom | applyTo
1 0 2016-01-01 00:00.000 2016-01-01 01:99.999
1 1 2016-01-01 02:00.000 9999-31-12 00:00.000
2 0 2016-01-01 02:00.000 9999-31-12 00:00.000
我已经尝试迭代CURSOR
并随着时间的推移进行更新。
UPDATE orders SET applyFrom = @newApplyFrom, applyTo = @newApplyTo
WHERE id = @id AND revision = @revision;
但是有2.26亿行,估计运行时间接近60小时,甚至达到指数。
是否有更快的方法来实现相同的结果?我可以根据需要添加索引。目前,(id,revision)上有一个聚簇索引。
答案 0 :(得分:2)
您可以更新如下:我正在使用潜水并使用选择
显示;with cte as (
select *, lead(insertedAt,1,'9999-12-31 00:00.000') over(order by id) migdate from Orders
)
select *, case when insertedAt = migdate then '9999-12-31 00:00.000' else DATEADD(S, -1, migdate) end as applyto from cte
答案 1 :(得分:1)
这是一个包含LEAD
和自我加入的版本。不确定大数据集的性能,但我已经包括批处理以防万一。
WITH cte AS (
SELECT
id,
revision,
insertedAt,
applyFrom,
applyTo,
LEAD(insertedAt) OVER (PARTITION BY id ORDER BY id, revision) AS newApplyTo
FROM orders
)
UPDATE TOP (@BatchSize) o SET
applyFrom = o.insertedAt,
applyTo = ISNULL(DATEADD(s, -1, o.newApplyTo), '9999-12-31')
FROM cte o
WHERE
o.applyFrom IS NULL AND
o.applyTo IS NULL;
我使用的数据集(带结果)是:
Id revision insertedAt applyFrom applyTo
----------- ----------- --------------------------- --------------------------- ---------------------------
1 0 2016-01-01 00:00:00.0000000 2016-01-01 00:00:00.0000000 2016-01-01 01:59:59.0000000
1 1 2016-01-01 02:00:00.0000000 2016-01-01 02:00:00.0000000 9999-12-31 00:00:00.0000000
2 0 2016-01-01 02:00:00.0000000 2016-01-01 02:00:00.0000000 9999-12-31 00:00:00.0000000
3 0 2016-01-01 00:00:00.0000000 2016-01-01 00:00:00.0000000 2016-10-31 23:59:59.0000000
3 1 2016-11-01 00:00:00.0000000 2016-11-01 00:00:00.0000000 2016-11-30 23:59:59.0000000
3 2 2016-12-01 00:00:00.0000000 2016-12-01 00:00:00.0000000 9999-12-31 00:00:00.0000000