复合索引中列的顺序是否会影响查找速度?

时间:2014-11-25 15:44:12

标签: mysql performance indexing

我们来看下面的MySQL表:

CREATE TABLE prices (
  id          INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  countryCode CHAR(2) COLLATE ASCII_BIN NOT NULL,
  productId   INT(10) UNSIGNED NOT NULL,
  merchantId  INT(10) UNSIGNED NOT NULL,
  PRIMARY KEY (id),
  INDEX (countryCode, productId, merchantId)
) ENGINE=InnoDB;

我将在此表上进行的唯一查找是:

  • WHERE countryCode = ? AND productId = ?
  • WHERE countryCode = ? AND productId = ? AND merchantId = ?

因此索引可用于所有查询,这很好。

并非所有查询都包含merchantId,因此最适合用作复合索引中的最后一列。

现在关于前两列:我永远不会单独countryCodeproductId单独查找,所以乍一看我会打赌使用索引列订单(countryCode, productId, merchantId)(productId, countryCode, merchantId)在性能方面不应对我的用例产生任何影响,但我没有理论知识支持这一点。

鉴于productId s与countryCode s不同,{strong>有任何性能差异(不仅SELECT,还有INSERTUPDATEDELETE速度)改变索引中这两列的顺序,当它们总是一起使用时?

2 个答案:

答案 0 :(得分:1)

鉴于条件术语都是等于的,并且这些术语与AND结合,因此在改变索引中列的顺序方面,性能没有显着差异。

想一下电话簿。如果我让你抬头看“史密斯,约翰”,你抬头看史密斯部分,然后找到约翰。如果书的组织方式不同,按名字和姓氏,你会查找约翰节,然后找到史密斯。无论哪种方式,您都可以轻松缩小搜索范围。

有区别吗?可能略有不同,但它不足以担心。

如果条件等于,则规则会更改。首先在索引中将列放在等式比较中,然后在范围或不等式条件中放置一列。

您可能也喜欢我的演示文稿How to Design Indexes, Really。还有一个视频录像我在这里发表这个演讲:https://www.youtube.com/watch?v=ELR7-RdU9XU

答案 1 :(得分:1)

你的直觉是正确的。只要你的连接是equi-joins(使用=),那么你提到的两个索引中的任何一个都应该用于查询。 MerchantId需要成为继其他两个之后的第三个关键。

可能存在一些非常长的密钥的极端情况,其中CountryCodeProductId之间的排序会产生影响 - 比较长字符串比比较整数需要更长的时间。这些都与您的数据结构无关。

MySQL在查询中使用复合索引实际上有很好的documentation