MySQL 复合索引足以满足使用 JOIN 的查询吗?

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

据我了解,复合索引将完成以下情况所需的功能:

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

INDEX 将为 (id_city, id_type)。只要所有查询始终过滤这 2 个组合字段,就不需要其他索引。

但是如果查询中某个字段用于 JOIN 语句而另一个字段用于 WHERE 语句呢?示例:

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

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

解释当前选择: enter image description here

最佳答案

对于您的初始查询,是的,(id_city, id_type) 任意顺序都是最佳选择。加上 name last 会稍微好一点(因为被“覆盖”)。

继续...

对于该特定查询,具有以下索引:

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

这是发生的事情:

  1. 优化器在 WHERE 中看到 JOIN 以及有关其中一个表 (friends) 的一些内容,因此决定从 friend
  2. 要处理 WHERE,它需要一个以 WHERE 中的内容开始的索引,即 id_str
  3. 由于 friend 不需要太多其他内容,因此我们将所有列放入索引中,从而“覆盖”。 EXPLAIN 将通过 Using index 来表明这一点。
  4. 现在,转到另一个表(user)。 ON 子句需要 id_str,因此将其放在索引中第一个
  5. 再次,让我们通过添加名称来玩覆盖游戏。

我更笼统地介绍这些内容 here .

如果您的真实查询看起来在任何方面有所不同,那么一切就都失败了。也就是说,我建议的索引可能也可能有益。

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

  • 显示创建表
  • 真实查询。

关于MySQL 复合索引足以满足使用 JOIN 的查询吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50849345/

相关文章:

date - Access 2010+自动生成ID的日期+4位序号

Cakephp:在Sql日志中查询后打印注释

mysql - MySQL中加入同表临时表

mysql - 'sql_require_primary_key' - 在不创建主键的情况下无法将我的数据帧发送到 mysql 服务器

excel - 通过 INDEX MATCH 随机的另一个表的表头名称

MYSQL 查询优化 : build seperate tables with ORDER BY done so don't need indexes for SELECT ORDER BY

PostgreSQL 使用 UUID 与文本作为主键

mysql - 如何格式化这个 MySQL 查询?

mysql - 如何计算具有多个列条件的 MYSQL 表中的行数?

mysql - 上一次尝试在 MySql 上中断后无法创建 FULLTEXT 索引