2009-02-15 35 views
0

有问题的表是供应商软件在我们的网络上使用的数据库的一部分。该表包含有关文件的元数据。表的模式如下这是一个表的糟糕索引策略吗?

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

索引策略完全取决于您如何查询表以及您需要从各个查询中获得多少性能。

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

如果你不是绝对是需要跨越两个字段的聚集索引,那么不要。如果它更像是一种UNIQUE约束,那么通过一切手段使它成为一个UNIQUE约束。这些人不需要重新分类。

确定对表的典型查询是什么,并相应地放置索引。你有更多的索引,更慢的数据更改(插入/更新/删除)将会消失。不要创建太多的索引,例如在不太可能被过滤/排序的字段上。

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

+0

典型的查询将是非顺序插入,没有更新,没有删除,并且选择的频率不如插入(写入很多,读取很少)。我想我需要阅读并定期查看哪些查询正在运行。 – llamaoo7 2009-02-15 19:57:28

+0

这听起来像是删除聚集索引的好方案。另外,请查看索引填充因子。确保有足够的空间来减少索引页拆分的需要。默认的填充因子80可能对您的需求太高。 – Tomalak 2009-02-15 20:06:08

0

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

在下班时间有一项任务需要对索引进行碎片整理是一个不错的主意,不过您必须考虑频繁/随机插入操作,因此在表中留有一些空余空间以防止它受到伤害页面拆分(这会影响性能)。

1

看看你的疑问 - 那些打击数据的人。索引是否会提供服务?如果您按照(ResultID,FieldName)的顺序具有索引,但是您正在查询给定Fieldname的可能ResultID值,那么DBMS很可能会忽略该索引。相比之下,如果您有(FieldName,ResultID)上的索引,它可能会使用索引 - 当然可以用于简单值查找(WHERE FieldName = 'abc')。在唯一性方面,两个指数都表现良好;在查询优化方面,存在(至少潜在的)巨大差异。

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

集群与非集群索引通常是DBMS中的二阶优化效果。如果索引是正确的,则聚集索引与非聚集索引之间存在一个小差异(对于聚集索引,更小的更新罚分作为对较小选择时间的补偿)。在担心二阶效应之前,确保一切都已经过优化。

0

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

+1用于确定需要

至于我的背景,我是一个大学生,在这家公司工作的兼职

坚持学习,获得经验,但在此期间找一位经验丰富的顾问。

该表是通过运行4个线程每个

我想这是在工作日相当关键任务,和停机时间是个坏消息24名工人居住?如果是这样的话,不要使用它。

上有ResultID和字段名

一个聚集索引ResultID在PK的第一列,因为你说明什么?

如果是这样,我敢打赌它没有足够的选择性,并且根据查询的需求,PK字段的顺序应该交换(尽管这个复合键看起来是一个糟糕的选择集群PK)

什么结果:

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

如果第一计数,比方说,4个大如第二或更重要的是,由于ResultsID的选择性较低,因此您最有可能获得扫描优先搜索,并且一些简单的更改将会给予巨大的性能改进。

此外,字段名是相当宽(50个字符),所以任何二级索引将有50 + 4个字节添加到每个索引条目。这些字段是否真的是CHAR而不是VARCHAR?

就我个人而言,我会考虑增加叶页的密度。在90%的情况下,您只会留下一些差距 - 可能每页只有一个。但是对于一张5亿行的大型表格,较高的封装密度可能意味着树中的层次更少,因此需要更少的查找。相反,对于给定页面,几乎每个插入都需要分页。这将有利于集群插入,因此可能不合适(因为您的插入数据可能未集群)。像很多事情一样,你需要做一个测试来确定哪个索引密钥密度最好。SQL Server具有帮助分析查询如何被解析,它们是否被缓存,它们引起的表的扫描次数,哪些查询“运行缓慢”等等的工具。

请咨询顾问来看看并给你一些建议。这不是一个回答这里的问题将给你一个安全的解决方案来实现。

对于每天拥有500万行数据表和插入数据流的表,您真的需要仔细考虑维护策略。对不起,但我对进入这种状态的公司感到非常沮丧。

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

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