2017-01-24 12 views
0

Интересно, если подзапрос в следующем операторе обновления является хорошим (не коррелированным) или плохим (подзапросом)?Плохой (коррелированный) или хороший (не коррелированный) подзапрос?

Другими словами, мой вопрос в том, является ли это неэффективным запросом?

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

Нет такого правила, как «хороший (не коррелированный) или плохо (подзапрос) "! – jarlh

+4

И это не коррелировано - это просто подзапрос –

+0

Коррелированный подзапрос включает условие со ссылкой на основной запрос. – jarlh

ответ

0

подзапросов не по своей природе хорошо или плохо (можно было бы утверждать, что вместо SQL оптимизаторы плохо, а не подзапросов). Ваш пример не коррелирован вообще.

Вопрос о том, эффективен ли конкретный запрос или нет, требует анализа плана выполнения. Это, в свою очередь, в основном зависит от распределения данных, индексов и схем разбиения на данные. Нет ничего a priori плохо о вашем запросе.

Существуют и другие способы написания логики. Мне нравится этот:

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.

+0

* Ваша версия никогда не будет обновлять значение NULL. * => Какое значение NULL не будет обновлено? – beta

+0

Строка, где 'field2' является' NULL', никогда не будет обновляться. –

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 

выполняет оба запроса, как правило, использовать тот же план выполнения, и оба имеют одинаковую стоимость, как well..so мы не можем предположить, коррелированные подзапросы не будут работать лучше

enter image description here

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

для выше коррелируют subquery, SQL не может получить доступ к таблице заказов только один раз и выполнить все вычисления, ему нужно будет дважды обращаться к таблице .. это только то, что я мог видеть с коррелированными подзапросами

 Смежные вопросы

  • Нет связанных вопросов^_^