MySQL的复合索引是否足以使用JOIN的查询?

时间:2018-06-14 03:52:44

标签: mysql indexing primary-key composite-primary-key

据我所知,复合索引将完成以下情况所需的内容:

SELECT name FROM user WHERE id_city = 3 AND id_type = 5

INDEX 将是(id_city,id_type)。只要所有查询总是过滤那两个组合字段,就不需要其他索引。

但是,在JOIN语句中使用其中一个字段而在WHERE语句中使用另一个字段的查询呢?例如:

SELECT user.name AS name
FROM user JOIN friend ON friends.id_str = user.id_str
WHERE friends.id_user = 3

朋友表中的(id_user,id_str) INDEX 是否足够? (顺便说一句,我不是在询问用户表,这当然是另一种情况)。

当前SELECT的EXPLAIN: enter image description here

1 个答案:

答案 0 :(得分:1)

对于您的初始查询,是的,(id_city, id_type) 按任意顺序是最佳的。对name 最后的处理会稍好一些(因为“覆盖”)。

继续......

对于特定的查询,请使用以下索引:

friend:   (id_user, id_str)  -- in this order; "covering"
user:     (id_str, name)     -- in this order; "covering"

以下是发生的事情:

  1. 优化工具会在JOIN中看到friends及其中一个表(WHERE)的某些内容,因此它决定以friend开头。
  2. 要处理WHERE,它需要一个索引开始,其中包含WHERE中的内容,即id_str
  3. 由于friend不需要太多其他内容,我们将所有列放在索引中,因此“覆盖”。 EXPLAIN会通过说Using index
  4. 来表明这一点
  5. 现在,转到另一张桌子(user)。 ON子句需要id_str,因此将首先放在索引中。
  6. 再次,让我们通过添加name来发挥覆盖游戏。
  7. 我更一般地涵盖了这些内容here

    如果您的真实查询以任何方式看起来不同,则所有投注均已关闭。也就是说,我建议的索引可能或者可能不是是有益的。

    如果您想进一步讨论,请提供

    • SHOW CREATE TABLE
    • 真实的查询。