繁体   English   中英

编写此查询的更好/更有效的方法

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM