MySQL复合索引的最佳排序方法是什么?

26

我正在研究在一个MySQL数据库中的一个表中添加一个复合索引,该表可能会有几百万行。该复合索引将由两个varchar列和三个int列组成。

我的问题如标题所述:创建这个复合索引的最佳顺序是什么?

例如,其中一个int行可能只有6个可能的值,那么把该列放在索引定义的前面是否更好?同样,其中一个varchar列可能有数百万个不同的值,那么将其放在索引定义的前面或后面是否更好?


你在WHERE子句中使用常量进行选择,而不是范围吗? - Marcus Adams
马库斯,我可能会选择使用常量来查询这个表。 - chicagoCrazy
1个回答

50
作为经验法则,在多列索引中,您希望具有最高基数或者换句话说,具有最高数量不同值的列出现在索引的最前面。更确切地说,您希望搜索条件可能匹配最少的列首先出现,以便尽可能缩小结果集,但通常情况下,这与具有最高基数的相同。因此,在您的示例中,您希望具有数百万个不同值的列出现在仅具有6个不同值的列之前的索引中。假设您只从数百万个值中选择一行,则可以更快地消除更多行。当考虑两个基数相似的列时,请将较小的列放在前面(INTEGER列优于VARCHAR列),因为MySQL可以更快地进行比较和迭代。需要注意的是,如果您使用范围进行选择(例如WHERE datecol > NOW()),则希望将范围列放在最右边,并将具有单个常量的列(例如WHERE id = 1)放在左边。这是因为索引只能用于搜索和排序到第一个范围值的点。

9
基数并不总是一个正确的标准:我有一张包含多列索引的表格,其中索引的第一列只有两个可能的值,而后续的列具有更高的基数。这种设计有效的原因是该索引是为了一种特定的搜索而设计的,该搜索始终仅使用这两个值中的一个,并且该值将结果集减少了95%。正确的问题是要问哪个列会最大程度地减少结果集,而基数只是一个有用的经验法则。 - Kai Pommerenke
4
@Kai,你的评论让我感到困惑。也许您可以举一个具体的例子。 - Marcus Adams
1
@MarcusAdams 我明白Kai的意思,我认为这篇文章解释得非常清楚:http://www.percona.com/blog/2009/06/05/a-rule-of-thumb-for-choosing-column-order-in-indexes/ - Shane N
谢谢,我刚刚看到了评论,我明白了。我根据评论改进了我的答案。 - Marcus Adams
什么被认为是“相似”的基数? - bermick
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接