[英]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%相同。 一个区别是,它像对待其他任何值一样对待field2
的NULL
值。 您的版本永远不会更新NULL
值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.