【问题标题】:mysql index column order for join用于连接的mysql索引列顺序
【发布时间】:2019-12-20 01:34:15
【问题描述】:

我有两个表(请求,结果)

请求: 电子邮件

结果: 电子邮件,已处理_at

我现在想获取所有具有相同电子邮件请求但尚未处理的结果:

SELECT * FROM results
INNER JOIN requests ON requests.email = results.email
AND results.processed_at IS NULL

我在每个单独的列上都有一个索引,但是查询很慢。所以我假设我需要一个多列的结果索引:

我只是不确定列的顺序:

ALTER TABLE results 
ADD INDEX results_email_processed_at (email,processed_at) 
ALGORITHM=INPLACE LOCK=NONE;

ALTER TABLE results 
ADD INDEX results_processed_at_email (processed_at,email) 
ALGORITHM=INPLACE LOCK=NONE;

【问题讨论】:

  • 每张表有多少行?你有什么索引?
  • 作为一般规则,您首先将“访问”列放在索引中,然后是“过滤”列。在这种情况下,索引应该是(email,processed_at)
  • 请求有约 6000 万,结果约 1.5 亿

标签: mysql join indexing


【解决方案1】:

任一复合索引都同样有益。

但是,如果您要获取表的 40%,那么优化器可能会选择忽略任何索引并简单地扫描表。

这是SELECT 的实际查询吗?如果没有,请向我们展示实际查询;一些看似很小的更改可能会对优化选项产生很大影响。

请提供EXPLAIN SELECT ...,以便我们了解它对当前索引的看法。如果存在相关的数据类型问题,请提供SHOW CREATE TABLE

【讨论】:

    【解决方案2】:

    尽管存在任何索引问题,但您明确询问了所有未处理的请求。你有一个 INNER JOIN 这意味着我想要从双方,所以你在 where 的 NULL 检查永远不会有资格。

    您需要对结果表进行 LEFT JOIN。

    至于索引,因为连接是在电子邮件上,所以我只会将 EMAIL 作为索引的主要组成部分。通过有一个覆盖索引并包含 processes_at 列会更快,因为它不必去原始数据页面来限定结果,但索引特别排序为 (email, processes_at) 所以 EMAIL 是第一个限定符,那么当它已被处理,以便完成查询需求字段。

    【讨论】:

      猜你喜欢
      • 2015-05-30
      • 2011-06-14
      • 1970-01-01
      • 1970-01-01
      • 2010-11-18
      • 2018-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多