我有一个1 TB,600米的行表,它有一个误导的索引列选择,特别是主键列上的聚簇索引,它从不在select查询中使用。
我想从此行中删除聚集索引,并在许多其他行上创建它。
表格目前是这样的:
colA(PK,nvarchar(3))[聚集指数pt b]
colB(PK,bigint)[聚集索引pt a]
colC(日期时间)[非聚集索引]
colD(Money)[非聚集索引]
colE(位)[无索引]
colF(位)[无索引]
colG(int)[no index]
更多非索引列
我想将其更改为:
colA(PK,nvarchar(3))[聚集索引pt a]
colB(PK,bigint)[非聚集索引]
colC(日期时间)[非聚集索引]
colD(Money)[聚集索引pt d]
colE(位)[聚集索引pt b]
colF(位)[聚集索引pt c]
colG(int)[聚集索引pt e]
更多非索引列
两个问题: 1)您认为此更改需要多长时间(消息结束时的服务器规范)。不幸的是,它是一个实时数据库,我不能在不知道它将要用多长时间的情况下停机。
2)在聚集索引中添加这么多列是不是很糟糕?更新几乎从未执行过。有许多插入和许多选择总是使用所有建议的索引行作为选择参数。
服务器规范:RAID 5,MS-SQL Sever 2005中的5 x 15kRPM驱动器以及一些使它们保持运行的位。
答案 0 :(得分:9)
首先,我会避免使聚集索引比它绝对要宽。将它分为五个部分似乎是反作用的。此化合物中的所有列聚集索引是否稳定,例如从不改变??
如果没有,我会不惜一切代价避免它们。聚集索引应为:
您可以更改非聚集索引 - 没问题。但是要避免使聚集索引变得混乱!这肯定会降低你的表现!
查看Kimberly Tripp关于索引的优秀博客文章:
马克
答案 1 :(得分:6)
我做了改动,但没花太长时间。 以下是每个操作的时间,第一次是在具有单个7200RPM驱动器的备份服务器上运行,第二次是在主服务器上,在RAID中具有15k驱动器。
ALTER TABLE Table DROP CONSTRAINT [PK_Table]
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]
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]
4小时/ 1小时
现在最常用的选择查询需要< 10秒钟,通常需要10到15分钟。好的改进!插入时间似乎也快一些。
答案 2 :(得分:3)
您应该拥有一个具有类似规范的开发环境,您可以使用它来获取实时数据库的副本。
答案 3 :(得分:2)
虽然更改聚簇索引听起来像肯定会有帮助,但为什么不先尝试添加(非聚集)覆盖索引?
在构建新索引时不应该删除表,并且应该指示哪些性能改进(如果有)将导致此重组。
答案 4 :(得分:0)
您可能不需要担心停机时间,因为它可能是possible to do the change live(没有任何停机时间)。适用于SQL Server 2005 Enterprise Edition。
答案 5 :(得分:0)
如果有磁盘空间,可以做的一件事就是使用正确的聚簇索引创建第二个表,通过增量过程将这些行复制到新表中几天。一旦所有行都存在,就会在两个表上执行sp_rename(这只需要几分钟的停机时间。如果您的应用程序引用了一个视图而不是物理表,那么您可以完成此操作,并且不会对应用程序造成停机。我希望这有助于
[编辑] 您还必须处理对行的更新,您需要在源表上提供时间戳或上次更新的字段,以便在复制完所有行后同步更新。
答案 6 :(得分:0)
1)您认为此更改需要多长时间(消息结束时的服务器规范)。不幸的是,它是一个实时数据库,如果不知道它将持续多长时间,我就无法停机。
确实,真的取决于数据。仅仅表参数不能提供足够的信息。可能是几分钟(不太可能)到几天(不太可能),最有可能的时间介于两者之间。
2)在聚集索引中添加这么多列是一个可怕的想法吗?更新几乎从未执行过。有许多插入和许多选择总是使用所有建议的索引行作为选择参数。
不,这不应该造成任何问题。只有在进行少量更新时才能提高性能。当这些更新发生时,修复索引需要一段时间,并且在此期间性能将受到影响,这将根据数据而变化。
- 亚当
答案 7 :(得分:0)
我同意Brian的意见,你应该有一个具有相同数据量的测试数据库并运行索引更改。但是,我认为您正在进行此更改,因为您认为它会加快查询速度。您应该运行基准测试(在索引更改之前和之后),并确保您的优化不会变成悲观。