[英]A better / more efficient way to write this query
我正在尝试计算表中的记录数。 该表称为从属关系,只有4列(其中2个是外键)
我想计算附属列为0且business_id与特定account_email相关的记录数。
我知道如何使用IN关键字执行此查询,但是我想知道是否有更好或更有效的方法来执行此查询。
这是查询的IN版本:
SELECT COUNT(1) FROM affiliations
WHERE business_id IN (
SELECT business_id
FROM affiliations
WHERE account_email = 'address@domain.ext'
) AND affiliated = 0
我知道我可以用EXISTS代替它:
SELECT COUNT(1) FROM affiliations
WHERE EXISTS (
SELECT 1 FROM affiliations
WHERE account_email = 'address@domain.ext'
) AND affiliated = 0
带有EXISTS的语句行得通吗? 如前所述,有没有更好的方法呢?
提前致谢!
我会使用存在的,但也要记住将子查询与主表相关联,如下所示。
SELECT COUNT(1) FROM affiliations a
WHERE exists (
SELECT 1
FROM affiliations a1
WHERE account_email = 'address@domain.ext'
and a1.business_id=a.business_id
) AND affiliated = 0
来自带有IN
子句的问题的第一个查询不等同于带有EXIST
的第二个查询。
要使用IN
转换第一个查询,必须使用一个依赖子查询:
SELECT COUNT(1) FROM affiliations a1
WHERE EXISTS (
SELECT 1 FROM affiliations a2
WHERE account_email = 'address@domain.ext'
AND a1.business_id = a2.business_id
) AND affiliated = 0
请注意以下情况: AND a1.business_id = a2.business_id
上面的查询在语义上等同于您使用IN
进行的第一个查询。
它们的性能也相同,因为MySql在优化阶段会内部转换以下形式的条件:
outer_expr IN (SELECT inner_expr FROM ... WHERE subquery_where)
到这个:
EXISTS (SELECT 1 FROM ... WHERE subquery_where AND outer_expr=inner_expr)
有关详细信息,请参见此链接: http : //dev.mysql.com/doc/refman/5.0/en/subquery-optimization-with-exists.html
请特别注意有关NULL值以及NULL如何影响优化器的讨论。
简而言之-如果将business_id
列声明为NOT NULL
,则MySql可以优化这两个查询。
请参阅最终结论(在此链接页面底部):
为了帮助查询优化器更好地执行查询,请使用以下提示:
如果确实是一列,则必须将其声明为NOT NULL。 (这也有助于优化程序的其他方面。)
如果您不需要将NULL与FALSE子查询结果区分开,则可以轻松避免执行路径缓慢。 替换如下所示的比较:
external_expr IN(从...选择inner_expr ...)
具有以下表达式:
(outer_expr不为空)和(outer_expr IN(选择FROM的inner_expr ...))
然后,永远不会对NULL IN(SELECT ...)进行求值,因为一旦表达式结果清除,MySQL就会立即停止对AND部件求值。
使用JOIN代替IN。 如果您尝试匹配许多值,则IN会降低性能
SELECT COUNT(1)
FROM affiliations AS ABB2
JOIN (SELECT business_id
FROM affiliations
WHERE account_email = 'address@domain.ext') AS ABB1
ON ABB1.business_id = ABB2.business_id
WHERE affiliated = 0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.