【问题标题】:Why having each column only in a single index in MySQL and does the order of columns in the query matter?为什么每列只在 MySQL 的一个索引中,并且查询中列的顺序很重要?
【发布时间】:2012-12-18 04:54:48
【问题描述】:

我经常在表posts 中搜索user+status 和user+time 列中的值。

SELECT * FROM `posts` WHERE `user`='xxx' and `status`='active'
SELECT * FROM `posts` WHERE `user`='xxx' and `time`>...

因此我设置了两个索引(用户,状态)和(用户,时间)

我知道,需要更新的索引越多,写入过程就越慢。但我认为在这种情况下,同时拥有两个索引很有用,因为读取操作的数量远远超过写入操作。

无论如何,PHPMyAdmin 会发出警告说“为列用户创建了多个索引”。我可以忽略这个警告吗?我检查了 Wordpress DB 表,发现它们已经在第二个位置放置了一列,如果它已经有索引的话。

comment_approved_date_gmt = INDEX(comment_approved, comment_date_gmt)
comment_date_gmt = INDEX(comment_date_gmt)

他们为什么不只使用一个两列索引 (INDEX(comment_date_gmt, comment_approved)),这样可以节省 INDEX(comment_date_gmt)?为什么有两个以相同列名开头的索引是不利的?

是否有一个通用规则,即在我的查询中应该首先显示哪一列?例如,不同条目数量最少的条目(例如状态),然后是不同值数量较多的条目(例如用户名)

【问题讨论】:

  • 一般来说,人们希望尽可能快地到达所需的记录(即比较少),并且 MySQL 索引是按照其组成列的命名顺序构建的(左-向右)。因此,在所有其他条件相同的情况下,人们会希望列从高基数到低基数排序;也就是说,所有其他事情很少是平等的,人们通常希望优先考虑某些列以适合希望使用索引的查询。
  • 您不需要将列名放在反引号中。

标签: mysql indexing query-optimization


【解决方案1】:

是的,索引中列的顺序很重要。

想想电话簿的类比。这就像 (last_name, first_name) 上的索引。通过姓氏查找某人,您可以使用电话簿的排序顺序来帮助您快速找到他们。

但如果你只知道这个人的名字,他们就会分散在整本书中。要找到一本,您必须逐页搜索。

是的,索引可以是多余的。

任何搜索 last_name 的查询都可以在 (last_name) 上使用单列索引,或者它可以从 (last_name, first_name) 上的两列索引中获得相同的好处。那么为什么要创建两个索引呢?

有一个工具pt-duplicate-key-checker 可以帮助您识别冗余索引。我从来没有遇到过没有至少几个这样的索引的数据库。

phpMyAdmin 错误。

如果 phpMyAdmin 对索引 (user, status) 和 (user, time) 发出警告,那么它就过于热心了,因为这些索引彼此之间不是冗余的。基本上,如果索引的列包含另一个索引中的列的左前缀,则该索引是冗余的。因此,索引 (A) 相对于索引 (A, B) 是冗余的,但索引 (A, C) 与 (A, B) 不同,两者都可能被不同的查询使用。

PS:我在演示文稿How to Design Indexes, Really 中介绍了这些要点和更多内容。

【讨论】:

    【解决方案2】:

    我觉得 SQL 查询中的列排序是一种过早的优化,根据 Knuth 的说法,这是万恶之源。您应该为维护而不是优化而编程,让优化器负责速度。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-19
      • 1970-01-01
      相关资源
      最近更新 更多