【问题标题】:MySQL-inner join is so slow even with indexing即使有索引,MySQL-inner join 也很慢
【发布时间】:2021-01-19 19:32:00
【问题描述】:

我的数据库中有两个表:tabel1,table2:

table1: {id, name, code, timestamp}
table2: {id, tag1, tag2, tag3}

已在两个表的所有列上创建索引。现在我想运行以下查询:

SELECT a.* FROM table1 a
INNER JOIN table2 AS b
ON a.id=b.id
WHERE b.tag1=true
ORDER BY a.timestamp DESC, a.id DESC
LIMIT 24

但它很慢(几乎 5 秒,两个表都有 1M 行)。当我从查询中删除 WHERE b.tag1=true 时,它会在 0.1 秒内运行。是什么让这个查询如此缓慢以及如何解决它?

索引:

table1: {id: index, name: index, code: index, timestamp: index, (id, timestamp): index}
table2: {id:primary, tag1: index, tag2: index, tag3: index}

【问题讨论】:

  • 请显示已创建的索引。
  • @GordonLinoff 我更新了我的帖子。
  • Table2 看起来设计不佳。我会从那开始。
  • @Strawberry 为什么你认为它的设计不好?
  • 任何时候您发现自己使用枚举列名(例如,2 以上),您可以有理由确信您的架构设计不是最佳的。

标签: mysql sql indexing inner-join


【解决方案1】:

拼出索引的最佳方式是通过SHOW CREATE TABLE

不幸的是,JOIN 阻止了ORDER BYLIMIT 的有效使用。

b: INDEX(tag1, id)
a: INDEX(timestamp, id)

这个公式可能会更好:

SELECT a.*
    FROM  table1 a
    INNER JOIN  table2 AS b  ON a.id=b.id
    WHERE EXISTS( SELECT 1 FROM table2 WHERE id = a.id AND tag1 = true )
    ORDER BY  a.timestamp DESC, a.id DESC
    LIMIT  24

请为您的版本和我的版本提供EXPLAIN SELECT ...

tag1 通常是真的吗?也就是说,a 的大部分行会被过滤掉还是保留?

如果id 是两个表的PRIMARY KEY,为什么有两个单独的表?

【讨论】:

  • 不幸的是,您的查询甚至需要更长的时间才能执行。
猜你喜欢
  • 2016-12-04
  • 1970-01-01
  • 1970-01-01
  • 2014-01-21
  • 2020-06-01
  • 2013-04-20
  • 1970-01-01
  • 1970-01-01
  • 2015-12-31
相关资源
最近更新 更多