如何在 WHERE 子句中优化使用 COALESCE()?
Posted
技术标签:
【中文标题】如何在 WHERE 子句中优化使用 COALESCE()?【英文标题】:How can I use COALESCE() in WHERE clause optimally? 【发布时间】:2018-06-16 13:48:18 【问题描述】:这是我的查询:
select coalesce(qa2.subject, qa.subject) as question_subject,
qa.body,
(select count(*)
from viewed_items vi
where coalesce(qa.related, qa.id) = vi.question_id
) as total_question_viewed
from questions_and_answers qa
left join questions_and_answers qa2 on qa.related = qa.id
where body like ':entry';
如您所知,mysql 优化器永远无法在 coalesce(qa.related, qa.id) = vi.question_id
上使用索引。那么知道如何才能更优化地编写此查询吗?
【问题讨论】:
试一试where vi.question_id in(qa.related, qa.id)
,确保检查两个查询的解释计划
【参考方案1】:
您可以使用两个单独的子查询进行计算:
select coalesce(qa2.subject, qa.subject) as question_subject,
qa.body,
( (select count(*)
from viewed_items vi
where qa.related = vi.question_id
) +
(select count(*)
from viewed_items vi
where qa.related is null and qa.id = vi.question_id
)
) as total_question_viewed
from questions_and_answers qa left join
questions_and_answers qa2
on qa.related = qa.id
where body like ':entry';
索引可用于每个子查询,因此总体上应该更快。顺便说一句,您不必担心NULL
的值,因为相关子查询中的COUNT(*)
总是返回一个值。如果没有匹配项,则值为0
。
【讨论】:
您的问题完全正确。谢谢,点个赞。应该注意的是,我不能像where vi.question_id in(qa.related, qa.id)
那样使用IN
子句。因为和where coalesce(qa.related, qa.id) = vi.question_id
不一样。
还有@Gordon,请看一下this question .. 我想只有你才能为它写一个性感的答案。
@Martin AJ 是的,你实际上可以使用where vi.question_id in(qa.related, qa.id)
如果它有帮助的话——但不是唯一的,因为你是对的,它不等同......所以你需要使用@987654330 @。优化器是生产惰性的专家,如果可能,它将使用索引解析第一个谓词,然后使用第二个进行过滤。这是可行的,因为一个是另一个的超集。以上是关于如何在 WHERE 子句中优化使用 COALESCE()?的主要内容,如果未能解决你的问题,请参考以下文章