表大小 = 44GB(无聚集索引)
行数 = 122016576
分配给 tempdb 的磁盘空间 = 200MB
由于查询时间慢,我想为表创建一个聚集索引,所以我运行了以下查询:
USE [myDatabase]
GO
CREATE CLUSTERED INDEX [IX_Name] ON [dbo].[myTable]
(
[myColumn] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = ON, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
执行 50 分钟后,我的服务器的 tempdb 文件(总共 4 个)空间不足,数据库进入“恢复中”状态大约 10 分钟。它现在已经启动并运行,但是当我特别说 SORT_IN_TEMPDB = OFF 时,我很困惑为什么 tempdb 被如此使用。
有谁知道为什么这个操作使用了这么多 tempdb 空间?
虽然你有
SORT_IN_TEMPDB = OFF
,但这不是唯一使用 tempdb 的东西。你也设置了ONLINE = ON
。由于该作业在您遇到问题之前运行了 50 分钟,因此您在该单个事务中可能有足够的活动来填充
tempdb
行版本控制数据。此处对此进行了描述:http://technet.microsoft.com/en-us/library/ms179542.aspx
它部分说:“在线索引操作使用行版本控制将索引操作与其他事务所做修改的影响隔离开来。......在线索引操作期间并发的用户更新和删除操作需要用于版本记录的空间
tempdb
。”编辑:实际上,对于具有 44 GB 表的数据库来说,200 MB
tempdb
似乎很小。它必须在某个位置对聚集索引的数据进行排序,然后按该顺序重写您的行。
不要忘记 SQL Server 会添加一个额外的整数,即“唯一标识符”,以便消除“myColumn”的非唯一值之间的歧义。这将导致所有非聚集索引包含“myColumn”+“uniquifier”(4 字节)。