2013-02-27 59 views
0

我从来没有设计过一个大型数据库,所以我从不关心索引。但是,现在我正在开发一个需要大型数据库的大型项目。因此,我正在识别每个将在内部联接上使用它作为索引的表。在一张大桌子上的多场索引是一个好主意吗?

只是作为一个例子的大的表中的一个具有字段是这样的:

Userid 
Industryid 
Teamid 
Zoneid 

任何与我想是一个识别指向第二个表。所以我已经将这些索引。

此表有60个字段,但其中16个索引+ 1个主字段。

如果这是一个好主意,有这么大的表与所有这些指标?我期待这张表能在1年内超过400万条记录。我之所以做这样的事情是为了让这张表与其他表格之间的内部连接更容易和更快速。

什么是在这样一个大型项目中使用索引的最佳方式?

+0

所有这四个字段看起来都可能是外键。这四个组合*可能*是一个自然主键。我无法讲述其他12个指数,但是具有60个字段和12个指数的表格看起来有点可疑,与数据模型有关。 – wildplasser 2013-02-27 13:33:24

+0

其中12个是外键,4个是可搜索的。所以对于eaxample我有userid和用户名eventhh我有用户名是第二个表称为uses。而且我不确定我是否在这里做了正确的调用,但是这会在这么大的桌子上放下1个内部连接。再加上它将用户名称保留在历史记录中,即使用户名称因任何原因而被更改。 – Jaylen 2013-02-27 16:26:45

+0

使用16张FK的单张桌子违反了3NF/BCNF或艺术作品。避免(内部)连接的反规范化听起来像是过去的不良习惯,IMnsHO。 – wildplasser 2013-02-27 16:38:47

回答

1

此表有60个字段,但其中16个索引+ 1个主字段。

看起来有点过分,但如果你真的需要所有这些指标那么它的确定。

索引不是免费的:每增加一个索引都会占用空间,并且在修改数据时需要维护,以便在搜索数据时(假设使用正确)加快速度。您需要为您确定适合您的特定情况的权衡。

如果这是一个好主意,有与所有这些指标这么大的桌子吗?

在FK上有索引几乎总是一个好主意,所以DBMS可以保持FK具有良好的性能。具体来说,无论何时删除父行或更新引用的键,DBMS都必须搜索子行。从理论上讲,如果你永远不删除/更新父项,你也不会真的需要FK上的索引,尽管有些DBMS会强制你在任何情况下都拥有它们。

这些指标可以是(而且通常是)对JOINins有用,但实际上取决于如何你加入,以及如何能够为你的DBMS的查询规划。

在如此大的项目中使用索引的最佳方法是什么?

对于每个性能敏感的查询时,仔细检查查询执行计划和测量上代表数据量的实际定时。仅仅因为一个查询在一个小表上执行,doesn't mean它将在表增长时以相同的方式执行。

最后但并非最不重要的,我热烈推荐阅读Use The Index, Luke!


每一个行插入到表时,数据库管理系统必须插入索引B树对应的按键。当该行被删除时,该键将从索引中删除。当索引字段更新时,旧密钥需要被删除并插入新密钥。您在表上拥有的索引越多,无论何时在该表中插入/更新/删除行时,DBMS都必须花费更多的时间来执行“索引维护”。

有很多方法可以执行一个JOIN:以不同的顺序嵌套循环,合并连接,哈希联接...不同的策略可能需要不同的指标,甚至不同种指标(如B树不会为散列连接做很多好事)。并非所有DBMS都能够使用所有这些策略,也不能在所有情况下使用现有索引,理论上可以使用它们。因此,适用于一个DBMS的索引策略可能不一定适用于另一个DBMS。有时,您可以保留索引,但是您必须通过使用“查询提示”或使用对特定DBMS的查询优化器“友好”的语法来“正确”推动DBMS,尽管可能存在等效但更人类可读的语法。例如,旧版本的MySQL将始终执行IN子查询作为嵌套循环的内部,即使在循环或合并连接的反向顺序更快的情况下也是如此。这就是为什么人们经常在MySQL下推荐rewriting IN as JOIN(尽管我听说他们在MySQL 5.6中修复了这个问题)。 OTOH,在Oracle下重写IN作为JOIN并不是很有用,因为即使存在语法差异,Oracle在等效执行等价查询时也会更好。

+0

感谢您提供了如此好的反馈。当你说索引不是免费的并且需要维护时,你到底是什么意思?需要什么样的保养?你的意思是“你DBMS的查询计划员的能力如何”。感谢提示:) – Jaylen 2013-02-27 16:28:33

+0

@Mike我编辑了答案 - 请参阅脚注。 – 2013-02-27 17:40:16

+0

Branko,非常感谢你的帮助,这让我对它更加清楚:) – Jaylen 2013-02-27 19:50:55

相关问题