存储过程 - 截断 table
Stored procedure - truncate table
我创建了一个存储过程来将数据添加到 table。在模拟时尚中,步骤是:
- 截断原件table
- Select数据改成原来的table
将select的数据写入原始table的查询相当长(几乎需要一分钟才能完成),这意味着table然后是空的一分钟以上的数据。
为了修复这个空 table 我将存储过程更改为:
- select 数据进入#temp table
- 截断原始 table
- 将 #temp 中的 * 插入 Original
虽然存储过程是 运行,但我在原来的 table 上做了一个 select *
,它是空的(正在刷新,它一直是空的,直到存储过程完成)。
截断是否发生在过程的开头,而不管它在代码中的实际位置?如果是这样,我还能做些什么来控制何时删除数据?
一个非常有趣的方法将数据快速移动到table是使用分区切换。
使用 myStaging2
中的新数据创建两个分段 table,myStaging1
和 myStaging2
。它们必须在 same 数据库和 same 文件组中(所以不是临时 tables 或 table 变量), the EXACT same columns, PKs, FKs and indexes.
然后运行这个:
SET XACT_ABORT, NOCOUNT ON; -- force immediate rollback if session is killed
BEGIN TRAN;
ALTER TABLE myTargetTable SWITCH TO myStaging1
WITH ( WAIT_AT_LOW_PRIORITY ( MAX_DURATION = 1 MINUTES, ABORT_AFTER_WAIT = BLOCKERS ));
-- not strictly necessary to use WAIT_AT_LOW_PRIORITY but better for blocking
-- use SELF instead of BLOCKERS to kill your own session
ALTER TABLE myStaging2 SWITCH TO myTargetTable
WITH (WAIT_AT_LOW_PRIORITY (MAX_DURATION = 0 MINUTES, ABORT_AFTER_WAIT = BLOCKERS));
-- force blockers off immediately
COMMIT TRAN;
TRUNCATE TABLE myStaging1;
这非常快,因为它只是一个元数据更改。
您会问:分区仅在企业版(或开发版)上受支持,这有什么帮助?
即使在标准版或速成版中,仍允许在彼此之间切换未分区的 table。
有关此技术的更多信息,请参阅 this article by Kendra Little。
SP 正在由 HTTP Get 中的代码调用,因此我不希望 table 在刷新期间为空超过一分钟。当我问这个问题时,我正在使用 table 中的 select * 进行测试,但刚才我通过点击邮递员中的端点进行了测试,但我从未收到过空响应。所以看来将截断稍后放在 sp 中确实有效。
我创建了一个存储过程来将数据添加到 table。在模拟时尚中,步骤是:
- 截断原件table
- Select数据改成原来的table
将select的数据写入原始table的查询相当长(几乎需要一分钟才能完成),这意味着table然后是空的一分钟以上的数据。
为了修复这个空 table 我将存储过程更改为:
- select 数据进入#temp table
- 截断原始 table
- 将 #temp 中的 * 插入 Original
虽然存储过程是 运行,但我在原来的 table 上做了一个 select *
,它是空的(正在刷新,它一直是空的,直到存储过程完成)。
截断是否发生在过程的开头,而不管它在代码中的实际位置?如果是这样,我还能做些什么来控制何时删除数据?
一个非常有趣的方法将数据快速移动到table是使用分区切换。
使用 myStaging2
中的新数据创建两个分段 table,myStaging1
和 myStaging2
。它们必须在 same 数据库和 same 文件组中(所以不是临时 tables 或 table 变量), the EXACT same columns, PKs, FKs and indexes.
然后运行这个:
SET XACT_ABORT, NOCOUNT ON; -- force immediate rollback if session is killed
BEGIN TRAN;
ALTER TABLE myTargetTable SWITCH TO myStaging1
WITH ( WAIT_AT_LOW_PRIORITY ( MAX_DURATION = 1 MINUTES, ABORT_AFTER_WAIT = BLOCKERS ));
-- not strictly necessary to use WAIT_AT_LOW_PRIORITY but better for blocking
-- use SELF instead of BLOCKERS to kill your own session
ALTER TABLE myStaging2 SWITCH TO myTargetTable
WITH (WAIT_AT_LOW_PRIORITY (MAX_DURATION = 0 MINUTES, ABORT_AFTER_WAIT = BLOCKERS));
-- force blockers off immediately
COMMIT TRAN;
TRUNCATE TABLE myStaging1;
这非常快,因为它只是一个元数据更改。
您会问:分区仅在企业版(或开发版)上受支持,这有什么帮助?
即使在标准版或速成版中,仍允许在彼此之间切换未分区的 table。
有关此技术的更多信息,请参阅 this article by Kendra Little。
SP 正在由 HTTP Get 中的代码调用,因此我不希望 table 在刷新期间为空超过一分钟。当我问这个问题时,我正在使用 table 中的 select * 进行测试,但刚才我通过点击邮递员中的端点进行了测试,但我从未收到过空响应。所以看来将截断稍后放在 sp 中确实有效。