繁体   English   中英

错误(相关)或良好(不相关)子查询?

[英]Bad (correlated) or Good (not correlated) subquery?

我想知道,以下更新语句中的子查询是好(不相关)还是坏(子查询)?

换句话说,我的问题是,这是一个效率低下的查询吗?

UPDATE tableA
SET field1=0
FROM tableA
WHERE field2 IN (SELECT field2 
                 FROM tableA
                 WHERE someField IS NOT NULL 
                 AND someOtherField = 'ABC')

您的查询不相关,它只是一个子查询。

下面是一个相关的子查询。

UPDATE a
SET field1=0
FROM tableA a
WHERE exists  (SELECT 1
                 FROM tableB b
                 WHERE a.somecol=b.somecol)

相关子查询的另一个示例

select orderid,
(select custname from customers c where c.custid=o.custid) from orders o

以上查询可以写为join

select orderid,custname
 from orders o
 join
 customers c
 on c.custid=o.custid

执行这两个查询往往会使用相同的执行计划,并且两者的成本也相同。.所以我们不能假设,相关子查询的性能不会更好

在此处输入图片说明

select orderid,
(select count(orderid) from orders o2 where o2.custid=o.custid ) 
from orders o

对于上面的相关子查询,SQL不能只访问一次订单表并进行所有计算,它将需要访问表两次。这仅是我可以在相关子查询中看到的地方

子查询并不是天生的好坏(有人可能会说SQL优化器是坏的,而不是子查询)。 您的示例根本不相关。

特定查询是否有效的问题需要分析执行计划。 反过来,这主要取决于数据的分布,索引和数据的分区方案。 您的查询没有任何先验错误。

还有其他编写逻辑的方法。 我喜欢这一个:

WITH toupdate as (
      SELECT a.*,
             SUM(CASE WHEN someField IS NOT NULL AND someOtherField = 'ABC' 
                      THEN 1 ELSE 0
                 END) OVER (PARTITION BY field2) as cnt
      FROM tableA a
     )
UPDATE toupdate
    SET field1 = 0
    WHERE cnt > 0;

这不是100%相同。 一个区别是,它像对待其他任何值一样对待field2NULL值。 您的版本永远不会更新NULL值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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