【发布时间】:2020-05-16 17:09:56
【问题描述】:
这里有一个奇怪的。我有一个多表连接查询,其中为连接条件分配了正确的索引。当其中一个表设置为主连接(0.7 秒完成)时,查询将使用索引运行,但在另一个表设置时(189 秒完成)则不会。我希望有人可以帮助我理解为什么索引会在第二种情况下工作,而不是在第一种情况下。我已经包含了下面的连接条件以及每个查询的 EXPLAIN:
加入索引不起作用:
FROM
((
`fuse`
LEFT JOIN `occupancy` ON (((
CONVERT(substring_index(
`occupancy`.`last_name`,
'_',-(
1
)),UNSIGNED INTEGER) = `fuse`.`agent_id`
)
AND ( `fuse`.`login_date` = `occupancy`.`login_date` )))
LEFT JOIN `reporting_match` ON ((
`fuse`.`agent_id` = `reporting_match`.`agent_id`
)))
)
FROM
((
`occupancy`
LEFT JOIN `fuse` ON (((
CONVERT(substring_index(
`occupancy`.`last_name`,
'_',-(
1
)),UNSIGNED INTEGER) = `fuse`.`agent_id`
)
AND ( `fuse`.`login_date` = `occupancy`.`login_date` )))
LEFT JOIN `reporting_match` ON (
substring_index(
`occupancy`.`last_name`,
'_',-(
1
)) = `reporting_match`.`agent_id`
))
)
【问题讨论】:
-
也许是一个旁注:规范化架构并且不要将 ID 附加到名称。从名称中获取 ID 的函数调用会阻止索引用于该条件。
-
Edit 问题并提供minimal reproducible example 即至少表和索引的完整 DDL。还提供完整的查询,尤其是
WHERE子句。 -
谢谢,这个查询中没有 WHERE 子句,所以没有额外的内容。我想我只是要在导入时将该 ID 拆分为名称。不幸的是,我无法从为该表生成数据的系统中获得一个干净的 ID,但我可能会通过解析该 ID 来解决我的问题。
-
我认为是
LEFT JOIN,但我不确定。这可以解释dba.stackexchange.com/a/122856/191579 -
a LEFT JOIN b和b LEFT JOIN a在语义上是不同的。LEFT JOIN表示当“右”表中缺少一行时,将使用NULLs。