Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/93.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 大表上的多字段索引是个好主意吗?_Sql_Database Design_Indexing - Fatal编程技术网

Sql 大表上的多字段索引是个好主意吗?

Sql 大表上的多字段索引是个好主意吗?,sql,database-design,indexing,Sql,Database Design,Indexing,我以前从未设计过大型数据库,所以我从不关心索引。然而,现在我正在从事一个需要大型数据库的大型项目。因此,我要确定每个表,我将使用它作为内部连接的索引 例如,其中一个大型表具有如下字段: Userid Industryid Teamid Zoneid 任何带有我的东西都是指向第二张桌子的标识。所以我把它们编入了索引 此表有60个字段,但其中16个字段被索引为+1个主字段 有这么一个包含所有这些索引的大表是不是一个好主意?我预计这张表在一年内将超过400万条记录。。我这样做的原因是为了使这个表和其

我以前从未设计过大型数据库,所以我从不关心索引。然而,现在我正在从事一个需要大型数据库的大型项目。因此,我要确定每个表,我将使用它作为内部连接的索引

例如,其中一个大型表具有如下字段:

Userid
Industryid
Teamid
Zoneid
任何带有我的东西都是指向第二张桌子的标识。所以我把它们编入了索引

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

有这么一个包含所有这些索引的大表是不是一个好主意?我预计这张表在一年内将超过400万条记录。。我这样做的原因是为了使这个表和其他表之间的内部连接更容易、更快

在这么大的项目中使用索引的最佳方式是什么

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

这看起来有点过分,但如果您真的需要所有这些索引,那么就可以了

索引不是免费的:每个额外的索引都会占用空间,并且在修改数据时需要维护1,从而在搜索数据时加快速度(假设数据使用正确)。这取决于您为特定案例确定正确的权衡

有这么一个包含所有这些索引的大表是不是一个好主意

在FKs上建立索引几乎总是一个好主意,因此DBMS可以保持FKs具有良好的性能。具体来说,每当删除父行或更新引用的键时,DBMS都必须搜索子行。从理论上讲,如果您从不删除/更新父对象,那么您也不会真正需要FKs上的索引,尽管某些DBMS在任何情况下都会强制您拥有它们

这些索引可能(并且通常)对joinin有用,但这实际上取决于您如何加入以及DBMS的查询计划器的能力。2

在这么大的项目中使用索引的最佳方式是什么

对于每个性能敏感的查询,仔细检查查询执行计划,并测量代表性数据量的实际时间。因为查询是在一个小表上以一种方式执行的,所以当表增长时,它将以同样的方式执行

最后但并非最不重要的是,我强烈推荐阅读


1每次向表中插入一行时,DBMS都必须在索引B树中插入相应的键。删除该行时,将从索引中删除该键。更新索引字段时,需要删除旧密钥并插入新密钥。当您在表中插入/更新/删除一行时,表中的索引越多,DBMS就需要花费越多的时间来进行“索引维护”


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

所有四个字段看起来都可能是外键。这四个组合可能是一个自然的主键。我不能说出其他12个索引,但是一个包含60个字段和12个索引的表看起来有点可疑,数据模型是这样的。实际上,其中12个是外键,4个是可搜索的。例如,我有userid和username,尽管我有用户名,但第二个表是uses。我不确定我是否在这里做了正确的调用,但这将在如此大的表上删除1个内部联接。此外,即使用户名因任何原因被更改,它也会将用户名保留在历史记录中。拥有一个包含16个FK的表可能违反3NF/BCNF,也可能是一件艺术品。避免(内部)连接的非规范化听起来像是过去的坏习惯,IMnsHO。谢谢你这么好的反馈。当你说索引不是免费的,需要维护时,你到底是什么意思?需要什么样的维护?你的意思是“你的数据库管理系统的查询规划器有多大能力。”谢谢你的提示:)布兰科,非常感谢你的帮助,这让我更清楚了:)