【问题标题】:Does Index columns order in a (I have a 6 column index) affect speed? [duplicate]索引列的顺序(我有一个 6 列索引)会影响速度吗? [复制]
【发布时间】:2021-07-01 10:19:20
【问题描述】:

我有一个有 600 万行的表,我需要查找六列来选择项目。所以我创建了一个包含六列的索引。

更改索引中列的顺序会影响查询速度吗?

查询速度是否取决于每列具有的唯一项的数量?还是列上条件的可能结果总数?

我尝试重新排序索引中的列,查询速度似乎发生了一些重大变化

表:pic_tag_relations

列:

  • tag_id (int) (1-1,000,000)(基数:最低)
  • contrast_score(float) (0-24)
  • quality_score (float) (0-10)
  • pic_ratio_type(tinyint) (0/1/2)
  • is_okay (tinyint) (0/1)
  • already_used_count (integer) (1-10)

查询:

select * from pic_tag_relations where tag_id in ($all_tag_ids) && contrast_score>2.5 && quality_score>3 && is_okay=1 && pic_ratio_type='2' && already_used_count

【问题讨论】:

  • 最好先拥有最大基数的索引。
  • 是的,它确实有很强的效果。请将您将要运行的查询添加到问题中。
  • 我认为更具体的字段应该首先出现在索引中(但有些人可能不同意)。
  • 我的第一反应是:索引就是索引,不管它是如何构建的。但是the manual begs differ“如果在索引定义中以正确的顺序指定列,单个复合索引可以加速同一张表的多种查询。”
  • @KIKOSoftware 因为在顺序中跳过某些列的查询将无法利用完整索引。但问题是关于使用所有列的查询。

标签: mysql sql database


【解决方案1】:

索引中列的顺序会影响可以使用的查询。如果条件都相等,那么排序几乎没有区别。

首先使用具有大量值的键与具有少量值的键之间可能存在细微差别。但是,当索引被优化使用时,我不会担心性能的不同。

更重要的是让索引中的列具有相等条件是第一列(无论顺序如何),这样索引才能得到有效使用。

【讨论】:

  • 啊,我明白了,谢谢,这当然有帮助。我在查询中执行 3 次比较(
  • @Mrpoppins 。 . .具有相等条件的列应该是第一个。那么最严格的> 列应该是下一个。
【解决方案2】:

我在这里回答了几乎相同的问题:Does Order of Fields of Multi-Column Index in MySQL Matter

是的,列的顺序很重要。要选择正确的列顺序,您应该记住一个特定的查询。您尚未在此问题中显示查询。

如果您的查询条件都是= 比较,那么列的顺序无关紧要。有些人试图通过在左侧放置更多选择性列来进行微优化,但我发现这并没有显着差异。

例如,如果您在电话簿中按全名查找某人,您真的关心电话簿是按姓氏在前还是名字在前?无论如何,您都将过滤这两个字段。

但是,如果您同时使用 = 比较和其他类型的比较运算符,那么列顺序确实很重要。

基本上,您可以拥有任意数量的= 术语,并且这些比较的列必须位于索引中列列表的左端。然后你可以在索引中有 ONE 列进行不等式比较。您搜索的任何其他列都不会使用索引。

您在评论中提到您有一个与< 比较的查询。像这样:

... WHERE a < 1 AND b < 2 AND c < 3

这最多可以在其中一个列上使用索引。在这种情况下,您应该选择最具选择性的条件,即匹配行的最小子集。

如果使用的术语=

... WHERE a = 1 AND b = 2 AND c = 3

那么(a, b, c)上的多列索引的所有列都可以帮助搜索,列的顺序无关紧要。

如果您有多种比较:

... WHERE a = 1 AND b < 2 AND c < 3

那么你可能有一个索引,最左边的列是a,后面是bc 之一。但是,如果您同时拥有bc,则仍然只有一个用于搜索——a 之后的第一个。

查看我的演示文稿How to Design Indexes, Reallyvideo


使用示例查询来更新您的问题:

select * from pic_tag_relations where tag_id in ($all_tag_ids) && contrast_score>2.5 && quality_score>3 && is_okay=1 && pic_ratio_type='2' && already_used_count

您可以将(is_okay, pic_ratio_type) 作为第一列的索引,然后您可以选择其他列中的哪一列应该是第三列。其他列是根据使用除= 之外的一些比较运算符的术语来引用的。哪一列最好取决于每个条件选择较小的行子集的可能性。

其他术语也将过滤掉行,但不是通过使用索引。当索引搜索返回时,它们必须与行一一进行比较。

【讨论】:

  • 谢谢,我混合了相等和比较操作。我还没看过视频。通过“那么列顺序确实很重要。”我假设您的意思是“=”操作列必须放在左侧(索引中的第一个)
  • 我用更多示例更新了我的答案。
  • 谢谢。这当然有帮助,我会减少索引中的列数
猜你喜欢
  • 1970-01-01
  • 2014-06-05
  • 1970-01-01
  • 2010-11-30
  • 1970-01-01
  • 2012-11-16
  • 2017-07-04
  • 2023-03-03
  • 1970-01-01
相关资源
最近更新 更多