我想知道,如果以下更新语句中的子查询是好的(不相关)还是坏的(子查询)?
换句话说,我的问题是,这是一个效率低下的查询吗?
UPDATE tableA
SET field1=0
FROM tableA
WHERE field2 IN (SELECT field2
FROM tableA
WHERE someField IS NOT NULL
AND someOtherField = 'ABC')
答案 0 :(得分:1)
您的查询不相关,它只是一个子查询..
下面是一个相关的子查询..
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
以上查询可以写成连接
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只能访问一次订单表并执行所有计算,它需要访问表两次..这只是我能看到的相关子查询
答案 1 :(得分:0)
子查询本质上不是好的或坏的(人们可能会争辩说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%相同。一个区别是,这会像NULL
一样处理field2
值,就像任何其他值一样;您的版本永远不会更新NULL
值。