使用子查询优化 SQL 查询

Posted

技术标签:

【中文标题】使用子查询优化 SQL 查询【英文标题】:Optimizing SQL Query with Subquery 【发布时间】:2018-04-20 16:30:23 【问题描述】:

我有一个包含地址和组织名称的表格。在某些情况下,同一地址可以与多个组织相关联,而在其他情况下,同一地址-组织对有多个记录。也就是说:

Address    Orgname
Address1   Orgname1
Address2   Orgname2
Address2   Orgname2
Address3   Orgname3
Address3   Orgname4

我想运行一个选择查询,它为每个地址输出 1 行,如果存在 1:1 地址:组织名称关系,则为组织名称,否则为“多个”一词。也就是说:

Address    Orgname
Address1   Orgname1
Address2   Orgname2
Address3   Multiple

我编写了以下代码来完成此操作,但运行速度非常慢,我想知道如何优化它。子查询 X 返回不同的匹配地址:组织名称。子查询 Y 计算剩余并返回存在 1:many 关系的地址。它们自己跑得很快。然后,外部查询返回原始表,如果地址不在具有 1:many 关系的地址的子查询中,则返回不同的 Address 和 Orgname,如果是,则返回“Multiple”。

SELECT DISTINCT [Match Address], 
CASE WHEN [Match Address] in 
    (SELECT y.[Match Address] from 
        (SELECT x.[Match Address], count(x.ORGNAME) as [Count] from
            (SELECT DISTINCT [Match Address], ORGNAME
            FROM Table) x
        GROUP BY [Match Address]
        HAVING count(x.ORGNAME) > 1) y)
THEN 'Multiple' ELSE ORGNAME END as ORGNAME
FROM Table

我怀疑不是将子查询放在内存中并将其视为外部查询的表,而是使用嵌套循环并为表中的每条记录重新运行子查询。我只是没有足够的经验知道如何防止这种情况发生。

【问题讨论】:

执行计划显示什么? 仅供参考,您可能会更幸运地在dba.stackexchange.com 上发布此内容。 【参考方案1】:

我认为将查询写成这样更容易:

select address,
       (case when min(orgname) = max(orgname) then min(orgname)
             else 'Multiple'
        end) as orgname
from t
group by address;

【讨论】:

就是这个。在 68k 行上

以上是关于使用子查询优化 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

使用交叉应用子查询优化 sql 查询的问题

查询优化,(子查询)(sql-transact)

如何使用 WHERE IN 子查询优化 SQL 查询

一文终结SQL 子查询优化

优化 SQL 子查询进行统计

使用 from 中的子查询优化 SQL