MySQL 自定义存在查询性能

MySQL customized exists query performance

由于使用 Hibernate,我无法使用这样的 exists 编写 JPA 查询(我将其翻译为纯 SQL 查询):

SELECT EXISTS (SELECT * FROM account WHERE activated = true)

所以我必须编写一个替代查询来检查是否存在已激活的帐户。看了这个网站上的几个建议后,我看到了一个替代品:

select case when count(*)> 0 then true else false end from account where activated = true

我的问题是:这对性能不好吗,是短路查询吗。表示如果发现至少一个激活的帐户,查询是否停止执行?或者它必须获得所有激活的帐户然后在最后检查总结果是否大于零?

(这些评论特定于 MySQL with InnoDB。)

EXISTS() 运行直到找到匹配的第一行。 COUNT() 必须找到所有匹配项。因此,EXISTS 至少与 COUNT 一样快,可能快得多。

EXISTS returns truefalse
a > b returns truefalse
COUNT(*) returns 0 或超过 0;见下文
a = truea

效果相同

我的观点是:你不需要做任何类似 ...then true else false...

您可能会看到 false0true 为非零值。也就是说,> 0 也是不必要的(在您的示例中)。

对于您的具体问题,优化器不够智能,无法将 COUNT(*)>0 转换为 EXISTS

您的查询似乎很深入,为什么不只是一个简单的

select count(*) 
   from account 
   where activated = true

完成,您将返回一条记录并进行计数。但是,如果您只是想看看是否有任何帐户被激活,您所需要的只是

select 1
   from account 
   where activated = true
   limit 1

在这里,您强制限制为 1,因此一旦找到第一个符合条件的查询,查询就完成了,您可以继续 - 即使您的数据库有 1000 条(甚至数百万条)记录。