sql azure耗时的查询

时间:2014-04-23 01:48:50

标签: sql sql-server azure

我在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中执行。我不知道这里发生了什么。有人可以帮忙吗?谢谢!

2 个答案:

答案 0 :(得分:8)

我在包含100M行的表中遇到了同样的问题并联系了Microsoft支持。这是我得到的回复:

  

您无法在桌面上创建索引的原因是您   正面临着阻止平台的限制   大于2GB的交易。

     

索引的创建是依赖的事务操作   事务日志执行表页的移动。更多行   在表中意味着要在T-Log中放入更多页面。既然你的表   包含1亿条记录(这是一个相当大的数字),它是   很容易达到这个限制。

     

为了创建索引,我们需要改变方法。   基本上我们将使用临时(临时)表来存储   您在源表上创建索引时的数据   之前已从数据中清除。

     

行动计划:

     
      
  1. 创建与原始表相同但没有的临时表   任何索引(这使登台表成为堆)
  2.   
  3. 将数据从原始表移动到临时表(插入       更快,因为登台表是一个堆)
  4.   
  5. 清空原始表格
  6.   
  7. 在原始表上创建索引(此时事务应该几乎为空)
  8.   
  9. 将数据从登台表移回原始表(这需要一些时间,因为该表包含索引)
  10.   
  11. 删除登台表
  12.   

他们建议使用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回复。