Long 运行 批量插入锁定表
Long running Bulk Insert locking tables
我有一个存储过程,可以批量导入大量数据,每次导入超过 200 万行。该过程大约需要 45 分钟,在此期间,任何关联的 table 都将被锁定,无法访问。与后续访问 table 关联的等待是 LCK_M_SCH_S.
有没有办法避免这种等待?访问这些 table 的所有其他过程都是只读的,并且数据不必是完美的,所以脏读就可以了。或者检查锁是否存在,return 另一个结果。
片段:
BEGIN TRANSACTION;
BEGIN TRY
truncate table dbo.myTable
DECLARE @file varchar(500) = 'the dir'
DECLARE @sql varchar(1000)
SET @sql = '
BULK INSERT dbo.myView
FROM ''' + @file + 'file.txt''
WITH
(
FIELDTERMINATOR =''|'',
ROWTERMINATOR = ''\n'',
FIRSTROW = 2,
CODEPAGE = ''ACP''
)'
EXEC(@sql)
END TRY
BEGIN CATCH
--error stuff
END CATCH
IF @@TRANCOUNT > 0
COMMIT TRANSACTION
END
如果没有办法解决这个问题,我还有什么其他选择,批量导入临时 tables 并从那里更新可以解决这个问题吗?
一个选项可能是拥有 2 个数据副本并使用 VIEW
。该视图指向您的 table 的一个副本,您在另一个副本上进行批量操作。完成批量操作后,更新视图的定义以查看已完成批量操作的 table。
然后您更新原始 table 或在下次批量操作发生时更新那个,并且您每次都在视图中交换对象。虽然这不是一个理想的解决方案,但是,您无法像您想要的那样真正避免 table 锁;我从不建议 NOLOCK
查询提示。
如果这个答案有几个反对票,我不会感到惊讶,因为它不是很好,但它确实达到了目的。
换句话说,我会将 FROM ''' + @file + 'file.txt''
更改为 FROM ' + QUOTENAME(@file + 'file.txt','''')
。我不知道 @file
的值从何而来,但是,SQL 注入不是你的朋友。
我有一个存储过程,可以批量导入大量数据,每次导入超过 200 万行。该过程大约需要 45 分钟,在此期间,任何关联的 table 都将被锁定,无法访问。与后续访问 table 关联的等待是 LCK_M_SCH_S.
有没有办法避免这种等待?访问这些 table 的所有其他过程都是只读的,并且数据不必是完美的,所以脏读就可以了。或者检查锁是否存在,return 另一个结果。
片段:
BEGIN TRANSACTION;
BEGIN TRY
truncate table dbo.myTable
DECLARE @file varchar(500) = 'the dir'
DECLARE @sql varchar(1000)
SET @sql = '
BULK INSERT dbo.myView
FROM ''' + @file + 'file.txt''
WITH
(
FIELDTERMINATOR =''|'',
ROWTERMINATOR = ''\n'',
FIRSTROW = 2,
CODEPAGE = ''ACP''
)'
EXEC(@sql)
END TRY
BEGIN CATCH
--error stuff
END CATCH
IF @@TRANCOUNT > 0
COMMIT TRANSACTION
END
如果没有办法解决这个问题,我还有什么其他选择,批量导入临时 tables 并从那里更新可以解决这个问题吗?
一个选项可能是拥有 2 个数据副本并使用 VIEW
。该视图指向您的 table 的一个副本,您在另一个副本上进行批量操作。完成批量操作后,更新视图的定义以查看已完成批量操作的 table。
然后您更新原始 table 或在下次批量操作发生时更新那个,并且您每次都在视图中交换对象。虽然这不是一个理想的解决方案,但是,您无法像您想要的那样真正避免 table 锁;我从不建议 NOLOCK
查询提示。
如果这个答案有几个反对票,我不会感到惊讶,因为它不是很好,但它确实达到了目的。
换句话说,我会将 FROM ''' + @file + 'file.txt''
更改为 FROM ' + QUOTENAME(@file + 'file.txt','''')
。我不知道 @file
的值从何而来,但是,SQL 注入不是你的朋友。