这对于表来说是一个糟糕的索引策略吗?

时间:2009-02-15 19:40:50

标签: database sql-server-2005 clustered-index

有问题的表是供应商软件在我们的网络上使用的数据库的一部分。该表包含有关文件的元数据。该表的架构如下

Metadata 
ResultID (PK, int, not null) 
MappedFieldname (char(50), not null) 
Fieldname (PK, char(50), not null) 
Fieldvalue (text, null)

ResultID和Fieldname上有一个聚簇索引。该表通常包含数百万行(在一种情况下,它包含5亿行)。该表由24名工作人员填充,每个工作人员在处理数据时运行4个线程。这导致许多非顺序插入。处理后,我们的一些内部软件会在此表中插入更多数据。给定表的碎片至少为50%。在最大的表格的情况下,它是90%。我们没有DBA。我知道我们迫切需要一个数据库维护策略。就我的背景而言,我是一名兼职在该公司工作的大学生。

我的问题是,聚集索引是最好的方法吗?是否应该考虑另一个指数?对于此类型和类似的特殊DBA任务,是否有任何良好的参考资料?

4 个答案:

答案 0 :(得分:4)

索引策略完全取决于您查询表的方式以及退出相应查询所需的性能。

当进行无序插入时,聚簇索引可以强制在物理上(在磁盘上)重新排序行(这称为“页面拆分”)。在索引页面上没有可用空间的大型表中,这可能需要一些时间。

如果您绝对要求具有跨越两个字段的聚簇索引,则不要。如果它更像是一种UNIQUE约束,那么无论如何都要使它成为UNIQUE约束。不需要重新排序。

确定针对表的典型查询,并相应地放置索引。您拥有的索引越多,数据更改速度就越慢(INSERT / UPDATE / DELETE)。不要创建太多索引,例如在不太可能被过滤/排序的字段上。

仅在上一起过滤/排序的字段上创建组合索引。

答案 1 :(得分:1)

仔细查看您的查询 - 查找表中的数据。指数会服务吗?如果您按顺序在(ResultID,FieldName)上有索引,但是您要查询给定Fieldname的可能ResultID值,则DBMS可能会忽略该索引。相比之下,如果你有一个索引(FieldName,ResultID),它可能会使用索引 - 当然对于简单的值查找(WHERE FieldName = 'abc')。就独特性而言,任何一个指数都运作良好;在查询优化方面,(至少可能)存在巨大差异。

使用EXPLAIN查看您的DBMS如何处理您的查询。

群集与非群集索引通常是DBMS中的二阶优化效果。如果索引正确,则聚簇索引和非聚簇索引之间存在细微差别(聚簇索引的更新惩罚更大,因为选择时间略小)。在担心二阶效应之前,请确保其他所有内容都已优化。

答案 2 :(得分:0)

据我所知,聚集索引是可以的。关于其他索引,您需要提供在此表上运行的典型SQL查询。只是创建一个蓝色的索引永远不是一个好主意。 您在谈论碎片和索引,是否意味着您怀疑查询执行速度变慢?或者您只是想缩小/整理数据库/索引?

最好在非工作时间有一个任务对索引进行碎片整理是个好主意,尽管你必须考虑频繁/随机插入,但是在表中有一些备用空间来防止页面没有坏处拆分(确实会影响性能)。

答案 3 :(得分:0)

  
    

我知道我们迫切需要一个数据库维护策略。

  

+1用于识别需求

  
    

就我的背景而言,我是一名兼职在该公司工作的大学生

  

继续学习,获得经验,同时获得经验丰富的顾问。

  
    

该表由24名工作人员填充,每个工作人员运行4个线程

  

我认为这在工作日是非常关键的任务,停机是坏消息吗?如果是这样的话,请不要随意使用它。

  
    

ResultID和Fieldname上有一个聚簇索引

  

结果ID是PK中的第一列,如您所示?

如果是这样,我敢打赌它的选择性不够,根据查询的需要,应该交换PK字段的顺序(尽管这个复合键看起来是群集的不良选择) PK)

结果是什么:

SELECT COUNT(*),COUNT(DISTINCT ResultID)FROM MyTable

如果第一个计数是,例如,4倍于第二个或更大,您很可能会优先于搜索进行扫描,因为ResultsID的选择性较低,而一些简单的更改将带来巨大的性能改进。

此外,Fieldname非常宽(50个字符),因此任何二级索引都会在每个索引条目中添加50 + 4个字节。这些字段真的是CHAR而不是VARCHAR吗?

我个人会考虑增加叶页的密度。在90%时,您只会留下一些空白 - 可能只有一页。但是,如果有一个5​​亿行的大表,则较高的打包密度可能意味着树中的级别较少,因此检索的次数较少。与此相反,对于给定页面,几乎每个插入都需要页面拆分。这将有利于群集的插入,因此可能不合适(假设您的插入数据可能不是群集的)。像许多事情一样,您需要进行测试以确定哪种索引密钥密度最佳。 SQL Server提供了一些工具来帮助分析查询的查询方式,是否正在缓存它们,它们导致的表扫描数量,查询“慢速运行”等等。

请一位顾问去看看并给你一些建议。这是一个在这里回答的问题将为您提供一个安全的解决方案来实施。

您真的需要对每天有5亿行和大量插入的表格仔细考虑维护策略。对不起,但我对进入这个州的公司感到非常沮丧。

该表需要进行碎片整理(如果您没有聚集索引,您的选项会变少,所以请保持这一点,直到您确定有更好的候选者为止)。 “在线”碎片整理方法将对性能产生适度的影响,并且可以突然消失 - 如果它们超出时间/ CPU限制,可以安全地中止[尽管这很可能需要一些编程]。如果您有一个“安静”插槽,则使用它进行表碎片整理并更新索引的统计信息。不要等到周末才能一次性完成所有桌子 - 在每天安静的时间(大概是在夜间)尽可能多地做多次。

对表进行碎片整理可能会导致事务日志使用量大幅增加,因此请确保经常备份任何TLog(我们有一个10分钟的TLog备份策略,我们会在表碎片整理期间将其增加到每分钟,以便碎片整理过程不会成为所需的Tlog空间的定义!)