我在Sql Azure中有一个表包含大约6M行。 我想为它创建一个新索引。 cmd就像:
CREATE NONCLUSTERED INDEX [INDEX1] ON [dbo].Table1
(
[Column1] ASC,
[Column2] ASC,
[Column3] ASC,
[Column4] ASC
)
INCLUDE ( [Column5],[Column6])
大约15分钟后,发生错误
" Msg 10054,Level 20,State 0,Line 0
从接收结果时发生传输级别错误 服务器。 (提供者:TCP提供者,错误:0 - 现有连接是 被远程主机强行关闭。)"
我试了好几次,得到了同样的错误。 但是我已经执行了其他耗时的查询,例如:
插入table1(Col1,Col2,Col3)从表2中选择Col1,Col2,Col3
花了20分钟并成功返回。
查询在同一个Sql Azure DB中执行。我不知道这里发生了什么。有人可以帮忙吗?谢谢!
答案 0 :(得分:8)
我在包含100M行的表中遇到了同样的问题并联系了Microsoft支持。这是我得到的回复:
您无法在桌面上创建索引的原因是您 正面临着阻止平台的限制 大于2GB的交易。
索引的创建是依赖的事务操作 事务日志执行表页的移动。更多行 在表中意味着要在T-Log中放入更多页面。既然你的表 包含1亿条记录(这是一个相当大的数字),它是 很容易达到这个限制。
为了创建索引,我们需要改变方法。 基本上我们将使用临时(临时)表来存储 您在源表上创建索引时的数据 之前已从数据中清除。
行动计划:
- 创建与原始表相同但没有的临时表 任何索引(这使登台表成为堆)
- 将数据从原始表移动到临时表(插入 更快,因为登台表是一个堆)
- 清空原始表格
- 在原始表上创建索引(此时事务应该几乎为空)
- 将数据从登台表移回原始表(这需要一些时间,因为该表包含索引)
- 删除登台表
醇>
他们建议使用BCP在登台表和原始表之间移动数据。
查看event_log表...
select * from sys.event_log
where database_name ='<DBName>'
and event_type <> 'connection_successful'
order by start_time desc
..我发现了以下错误消息:
由于事务日志过多,会话已终止 空间使用。尝试在单个事务中修改较少的行。
答案 1 :(得分:2)
感谢您的回答!实际上,我也找到了根本原因
有一个解决方案,设置ONLINE = ON,在在线模式下,索引创建任务将分成多个小任务,因此T-Log不会超过2GB。
但是有一个限制,索引创建命令的'include列'不能是无限大小的对象,如nvarchar(max),如果是这样,命令将立即失败。
因此,在Sql Azure中,索引创建操作如下:
CREATE NONCLUSTERED INDEX [INDEX1] ON [dbo].Table1
(
[Column1] ASC,
[Column2] ASC,
[Column3] ASC,
[Column4] ASC
)
INCLUDE ( [Column5],[Column6])
如果之前失败,请采取以下措施
1.使用'online = on'创建索引
2.如果#1失败,意味着column5或column6是nvarchar(max),查询表大小,如果&lt; 2GB,使用online = off直接创建索引
3.如果#2失败,表示表格大小&gt; 2GB,那么没有简单的方法来创建索引而不涉及临时表,必须采取行动,因为ahkvk回复。