重新索引大表 - 我怎么搞砸了?

Mr.*_*ble 5 sql sql-server database-design sql-server-2005 indexed

我有一个1 TB,600米的行表,它有一个误导的索引列选择,特别是主键列上的聚簇索引,它从未在选择查询中使用.

我想从此行中删除聚集索引,并在许多其他行上创建它.

表目前是这样的:

  • colA(PK,nvarchar(3))[聚集索引pt b]

  • colB(PK,bigint)[聚集索引pt a]

  • colC(DateTime)[非聚集索引]

  • colD(Money)[非聚集索引]

  • colE(位)[无索引]

  • colF(位)[无索引]

  • colG(int)[无索引]

  • 更多非索引列

我想把它改成这样:

  • colA(PK,nvarchar(3))[聚集索引pt a]

  • colB(PK,bigint)[非聚集索引]

  • colC(DateTime)[非聚集索引]

  • colD(货币)[聚集指数pt d]

  • colE(位)[聚集索引pt b]

  • colF(位)[聚集索引pt c]

  • colG(int)[聚集索引pt e]

  • 更多非索引列

两个问题:1)您认为此更改需要多长时间(消息结束时的服务器规范).不幸的是,它是一个实时数据库,我不能在不知道它将会停机多久的情况下停机.

2)在聚簇索引中添加这么多列是一个可怕的想法吗?更新几乎从未执行过.有许多插入和许多选择总是使用所有建议的索引行作为选择参数.

服务器规范:RAID 5中的5 x 15kRPM驱动器,MS-SQL Sever 2005和一些位以保持它们运行.

mar*_*c_s 10

首先,我会避免使聚集索引比它绝对要宽.将它分为五个部分似乎是反作用的.这个复合聚集索引中的所有列都是稳定的,例如永远不会改变吗?

如果没有,我会不惜一切代价避免它们.聚集索引应该是:

  • 独特
  • 稳定
  • 尽量缩小

您可以更改非聚集索引 - 没问题.但是要避免使聚集索引变得混乱!这肯定会降低你的表现!

查看Kimberly Tripp关于索引的优秀博客文章:


Mr.*_*ble 6

我做了改动,但没花太长时间.以下是每个操作的时间,第一次是在具有单个7200RPM驱动器的备份服务器上运行,第二次是在主服务器上,在RAID中具有15k驱动器.

ALTER TABLE Table DROP CONSTRAINT [PK_Table]
Run Code Online (Sandbox Code Playgroud)

2:39/19分钟

CREATE CLUSTERED INDEX [IX_Clustered] ON [Table] 
(
 [a] ASC,
 [b] ASC,
 [c] ASC,
 [d] ASC,
 [e] ASC,
 [f] ASC
)WITH (PAD_INDEX  = ON, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, FILLFACTOR = 90, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = OFF) ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)

15:30/2小时

ALTER TABLE Table ADD CONSTRAINT
PK_hands PRIMARY KEY NONCLUSTERED 
(
 e,
 h
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)

4小时/ 1小时

现在最常用的选择查询需要<10秒,通常需要10到15分钟.好的改进!插入时间似乎也快一点.


Mar*_*usQ 0

您可能不需要担心停机时间,因为可以实时进行更改(没有任何停机时间)。适用于SQL Server 2005企业版。