Database design 什么';在两列上建立索引和分别在每列上建立索引有什么区别?

Database design 什么';在两列上建立索引和分别在每列上建立索引有什么区别?,database-design,indexing,Database Design,Indexing,我不熟悉数据库索引,如果表中有两列是索引的好选择,例如 [Posts]( [PostID] [int] IDENTITY(1,1) NOT NULL, [UserName] [nvarchar](64) NOT NULL, [ApplicationType] [smallint] NOT NULL, ... ) 在这种情况下,PostID将是主键聚集索引,然后我想做更多的索引,因为它是一个大表,我想对UserName和ApplicationType进行索引,现在

我不熟悉数据库索引,如果表中有两列是索引的好选择,例如

[Posts](    
   [PostID] [int] IDENTITY(1,1) NOT NULL,
   [UserName] [nvarchar](64) NOT NULL,
   [ApplicationType] [smallint] NOT NULL,
   ...
)
在这种情况下,PostID将是主键聚集索引,然后我想做更多的索引,因为它是一个大表,我想对UserName和ApplicationType进行索引,现在我应该分别对它们进行索引(一个对UserName,一个对ApplicationType)还是将它们作为一个整体进行索引(一个对UserName,一个对ApplicationType进行索引)?在我把它变成坏习惯之前,我可以拥有的索引数量有限制吗?一般来说,这方面的经验法则是什么

谢谢


Ray.

这个问题的答案实际上取决于您将如何在表上搜索。如果您的搜索几乎总是包含这两列,那么在这两列上创建索引是合适的。如果您将经常单独搜索每个字段,那么为每个字段创建单独的索引是合适的。最后,您可以拥有所有3个索引(一个复合索引,两个单列索引)——这取决于您使用列进行搜索的方式。把它想象成一个电话簿——如果你总是用姓和名搜索,你会找到你要找的东西。但是,如果你想在电话簿中搜索每个姓斯科特的人,你可能需要一个新的索引(LName,FName)。如果您想查找具有给定姓氏的所有人,您仍然可以使用(LName,FName)的多列索引进行查找


每个数据库在每个表的索引数、每个索引的列数等方面都有自己的限制。它们通常足够高,如果您在这里查看3个索引,就不必担心它们。另外,请记住,索引越多,维护它们(插入、更新、删除等)的成本就越高。

IIRC,经验法则是索引只能用于从某个点到左侧使用所有列的查找。例如,如果您查询(a)、(a、b)、(a、b、c)或(a、b、c、d),而不是查询(a、c),则可以使用(a、b、c、d)列上的索引

这是建立索引方式的结果;对最左边的列进行索引,然后为该列的每个值为下一列创建索引,依此类推


编辑:正如BQ所指出的,DBMS可以扫描索引中完整的“
a
”部分,并查找“
b
”部分(我不知道这是实际完成的)。但是,这并不像可以使用上述规则的索引那样快(也可能比完整表扫描快)


就我个人而言,我认为这不应该被故意利用。如果对给定的查询来说,perf已经足够重要了,并且您正在考虑需要什么索引,那么您最好为它提供正确的索引。

请记住复合索引的电话簿规则:电话簿有效地按姓氏、名字进行索引。这是一个复合索引

如果您搜索名为“Smith,John”的人,那么将名字作为索引的一部分会很有帮助。一旦你找到姓“史密斯”的条目,你就可以很快找到“约翰”

但是,如果你需要搜索每个名为“John”的人,那么电话簿的索引是没有帮助的——你必须搜索整本书


因此,如果您搜索索引中命名的第一列,或者第二列,等等,那么复合索引是很好的。但是如果您的搜索跳过了索引中最左边的列,那么这种搜索就没有用了。

对于大多数DBMS的最新(和最新)版本来说,这是不正确的。通常情况下,如果您在“c”列中查找某个内容,则扫描索引比扫描整个表更快。一如既往,分析您的查询计划。