好的。这是我尝试运行的内容:
USE tempdb;
SELECT TOP 1000000 IDENTITY(INT, 1, 1) Number
INTO Numbers
FROM sys.objects s1
CROSS JOIN sys.objects s2
CROSS JOIN sys.objects s3
CROSS JOIN sys.objects s4;
这是“让我成为数字表”的查询之一。
这就是问题所在。如果我在 SQL Server 服务(重新)启动后立即运行它,则需要很长时间。不像十秒钟那样永远,我希望它更快。永远一样,我一次不小心让它超过了两个小时,仍然不得不杀死它。我想它永远不会回来。通常在我的机器上运行它需要不到两秒钟的时间。
但是,如果我这样做:
USE tempdb;
SELECT TOP 1000000 IDENTITY(INT, 1, 1) Number
INTO Numbers
FROM sys.objects s1
CROSS JOIN sys.objects s2
CROSS JOIN sys.objects s3;
DROP TABLE Numbers;
SELECT TOP 1000000 IDENTITY(INT, 1, 1) Number
INTO Numbers
FROM sys.objects s1
CROSS JOIN sys.objects s2
CROSS JOIN sys.objects s3
CROSS JOIN sys.objects s4;
然后它会像您期望的那样工作——第一个SELECT运行不到两秒钟,第二个也是。为什么我不直接使用三表版本?因为没有足够的条目sys.objects使该数字立方等于一百万个结果行。但这已经不是重点了。
不管怎样,从现在开始,我可以重复那一秒DROP/SELECT…INTO我想要的次数,没问题。不知何故,第一个三表版本让它永远没问题。至少,直到下一次服务重新启动和/或机器重新启动。在这一点上,再次运行最后SELECT一次永远不会回来。再次。
这就是它开始变得更加奇怪的地方。如果我先将其SELECT还原为两表版本:
USE tempdb;
SELECT TOP 1000000 IDENTITY(INT, 1, 1) Number
INTO Numbers
FROM sys.objects s1
CROSS JOIN sys.objects s2;
DROP TABLE Numbers;
SELECT TOP 1000000 IDENTITY(INT, 1, 1) Number
INTO Numbers
FROM sys.objects s1
CROSS JOIN sys.objects s2
CROSS JOIN sys.objects s3
CROSS JOIN sys.objects s4;
这也使得第二次SELECT运行永远。 单表版本也是如此。不知何故,那个三桌版本很神奇!
这里发生了什么?为什么这么慢?
(在有人指出我正在创建一个永久表之前tempdb,是的,我知道。更改为实际的临时表没有任何区别。)
添加信息:
- 这是 SQL Server 2012 开发者版
EXEC sp_WhoIsActive @find_block_leaders = 1, @sort_order = '[blocked_session_count] DESC'(脚本为 XML,因此可以在此处阅读)的输出是:
<?xml 版本="1.0" ?>
<结果1>
<记录>
<dd hh:mm:ss.mss>00 00:10:45.066</dd hh:mm:ss.mss>
<session_id>52</session_id>
<sql_text><?查询 --
SELECT TOP 1000000 IDENTITY(INT, 1, 1) 数字
INTO数字
FROM sys.objects s1
交叉连接 sys.objects s2
交叉连接 sys.objects s3
交叉连接 sys.objects s4;
--?></sql_text>
<login_name>我自己的登录名已编辑</login_name>
<wait_info>(99ms)LCK_M_X</wait_info>
<CPU> 9,750</CPU>
<tempdb_allocations> 713</tempdb_allocations>
<tempdb_current> 702</tempdb_current>
<blocking_session_id>NULL</blocking_session_id>
<blocked_session_count> 0</blocked_session_count>
<读取> 583,273</读取>
<写> 537</写>
<physical_reads> 50</physical_reads>
<used_memory> 3</used_memory>
<status>暂停</status>
<open_tran_count> 2</open_tran_count>
<percent_complete>NULL</percent_complete>
<host_name>我自己的机器名称已编辑</host_name>
<database_name>tempdb</database_name>
<program_name>Microsoft SQL Server Management Studio - 查询</program_name>
<start_time>2013-11-23 23:48:19.473</start_time>
<login_time>2013-11-23 23:47:47.060</login_time>
<request_id>0</request_id>
<collection_time>2013-11-23 23:59:04.560</collection_time>
</记录>
</结果1>
更多补充信息:
为什么我把它放在 tempdb 中是因为它是旨在在原始安装上运行的脚本的一部分,并且 tempdb 保证在那里。正如我所说,更改为全局临时表并没有什么不同。


