我有一个带有内连接和一个左连接的 MySQL 查询,数据库中有大量数据,并且运行速度相当慢。这大致是我的查询:
SELECT
main_table.*
FROM
main_table
INNER JOIN
...
LEFT JOIN
second_table ON (main_table.id = second_table.ref_id AND second_table.type = 'foo' AND second_table.bar IS NULL
WHERE
second_table.id IS NULL
;
main_table
中的条目可能在 second_table
中具有一个或多个引用条目。我想从 main_table
获取所有结果,这些结果要么在 second_table
中没有结果,要么在第二个表中只有不相关的数据(type 'foo'
code> 或 bar
为 NULL)。
看看EXPLAIN,MySQL首先搜索bar IS NULL
,然后搜索type = 'foo'
,这仍然会会产生数千个结果,而首先检查 ref_id
只会留下很少的结果来检查其他条件。
我只有 ref_id
上的索引,而不是 type
或 bar
的索引,如果我可以首先获取 ref_id
的查询搜索。
--编辑:我注意到在数据库的副本上(其中包含实际数据并且运行缓慢)在 type
和 bar< 上也有一个索引
单独,所以这可能就是为什么 MySQL 更喜欢 bar
而不是其他键。我正在考虑跨越多个领域的键。--
有人知道如何优化这种查询吗?是否可以强制 MySQL 在 ON 条件下使用特定顺序?
<小时/>“解决方案”:我添加了一个涵盖所有相关字段的索引。
我不认为这是一个真正的解决方案,因为我相信,如果首先在索引 ref_id
上完成 JOIN,它也会更快。当这是唯一的索引时,它可能会这样做,但是我的同事出于某种原因想到在其他字段上单独添加索引,可能需要在我们应用程序的其他地方。
最佳答案
如果将“不相关”行移至 where 部分会发生什么? 在我看来,数据库应该更容易连接表,并且将使用索引
类似的东西
SELECT
main_table.*
FROM
main_table
INNER JOIN
...
LEFT JOIN
second_table ON main_table.id = second_table.ref_id
WHERE
second_table.id IS NULL OR
(second_table.type = 'foo' AND second_table.bar IS NULL)
关于MySQL LEFT JOIN ON 条件的顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43910982/