在SELECT INTO上锁定数据库

时间:2014-08-12 19:12:48

标签: sql-server sql-server-2012

我有一个返回大量行的查询,我使用SELECT INTO(而不是INSERT INTO)来避免出现事务日志问题。

问题是:当这个查询正在运行时,我可以读取对象但不在对象资源管理器中显示它们。例如,当我尝试扩展表项时,我会收到以下消息:

enter image description here

有没有办法避免这个问题?

2 个答案:

答案 0 :(得分:3)

正如M.Ali所解释的那样,SELECT INTO在你的新表上有一个表锁,它也锁定了SSMS试图查询的模式对象,以便构建树浏览器。

我建议调整查询,以便语句运行得更快。由于这是插入没有索引的Heap并且具有tablock,因此它将按照您的说明进行最少的记录。因此,语句的SELECT部分​​很可能导致事情变慢。查看该查询是否可以优化或分解为更小的部分,以便语句不会运行这么长时间。

或者,使用INSERT INTO以小批量执行插入(并且不指定tablock提示)

答案 1 :(得分:1)

现在这里是一个测试,你将回答你的问题......

在SSMS中打开查询窗口。写任何将返回任何数字或行的查询,可能只有一行或10行,并按如下方式执行

查询窗口1

BEGIN TRANSACTION;

SELECT *  
   INTO NEW_Test_TABLE
FROM TABLE_NAME

查询窗口2

现在打开另一个窗口并针对此NEW_Test_TABLE编写SELECT语句。

SELECT * FROM NEW_Test_TABLE

您的查询将永远不会执行,但不会返回任何结果(此时NEW_Test_TABLE仅存在于缓冲区中)。除非你回到第一个查询窗口并提交事务,否则如果你转到查询窗口1并且ROLLBACK TRANSACTION NEW_Test_TABLE将在缓冲区chache中存在一次并且不再存在于任何地方。

同样,当您执行的Select into语句中没有任何内容被提交到磁盘时,因此SSMS无法看到它也无法通过Object explorer向您显示任何相关信息。

所以答案是在执行查询时要耐心等待,让SQL Server将SELECT INTO事务提交到磁盘,然后您就可以通过VIA查询或通过对象资源管理器访问它。