Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 оптимизация условия  [new]
thorn0
Member

Откуда: Kiev
Сообщений: 20
Всем привет!
Дано такое условие в запросе:

(SELECT Count(*) FROM A WHERE P AND Q) = 1
OR
(SELECT Count(*) FROM A WHERE P) = 0

где A - таблица, P и Q - условия.

Когда смотрю план, вижу, что обе половины OR выполняются отдельными подзапросами к A и затем конкатенируются.
Как бы это так соптимизировать, чтобы остался только 1 подзапрос к A?
29 окт 09, 21:48    [7859186]     Ответить | Цитировать Сообщить модератору
 Re: оптимизация условия  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
Когда P истинно, условие получается таким
(SELECT Count(*) FROM A WHERE Q) = 1
OR
(SELECT Count(*) FROM A) = 0
А когда P ложно, то
(SELECT Count(*) FROM A WHERE 2*2=5) = 1
OR
(SELECT Count(*) FROM A WHERE 2*2=5) = 0
всегда выполняется (логическая истина) из-за второго тождества
Предлагаю такое условие:
NOT P
OR NOT EXISTS(SELECT * FROM A)
OR (SELECT COUNT(*) FROM(SELECT TOP 2 * FROM A WHERE Q)T)=1
29 окт 09, 22:26    [7859278]     Ответить | Цитировать Сообщить модератору
 Re: оптимизация условия  [new]
thorn0
Member

Откуда: Kiev
Сообщений: 20
iap,

P (как и Q) содержит ссылки на поля из A.
Вынести его из селекта поэтому не получится.
29 окт 09, 22:32    [7859293]     Ответить | Цитировать Сообщить модератору
 Re: оптимизация условия  [new]
ChA
Member

Откуда: Москва
Сообщений: 10989
thorn0

Дано такое условие в запросе:

(SELECT Count(*) FROM A WHERE P AND Q) = 1
OR
(SELECT Count(*) FROM A WHERE P) = 0

где A - таблица, P и Q - условия.


Как бы это так соптимизировать, чтобы остался только 1 подзапрос к A?

EXISTS(
	SELECT *
	FROM (
		SELECT
			COUNT(*) AS PCnt
			, SUM(CASE WHEN Q THEN 1 END) AS QCnt
		FROM A WHERE P
	) t WHERE PCnt = 0 OR QCnt = 1
)
?
29 окт 09, 22:44    [7859327]     Ответить | Цитировать Сообщить модератору
 Re: оптимизация условия  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
thorn0
iap,

P (как и Q) содержит ссылки на поля из A.
Вынести его из селекта поэтому не получится.
Действительно.
29 окт 09, 22:50    [7859346]     Ответить | Цитировать Сообщить модератору
 Re: оптимизация условия  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31177
thorn0
iap,

P (как и Q) содержит ссылки на поля из A.
Вынести его из селекта поэтому не получится.

select count(*) as count_P,
sum(case when Q then 1 else 0 end) as count_Q
FROM (SELECT top 2 * FROM A WHERE P) as t
29 окт 09, 23:08    [7859391]     Ответить | Цитировать Сообщить модератору
 Re: оптимизация условия  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31177
alexeyvg
select count(*) as count_P,
sum(case when Q then 1 else 0 end) as count_Q
FROM (SELECT top 2 * FROM A WHERE P) as t
А ответ ChA я и не заметил :-)
29 окт 09, 23:11    [7859398]     Ответить | Цитировать Сообщить модератору
 Re: оптимизация условия  [new]
thorn0
Member

Откуда: Kiev
Сообщений: 20
ChA,
да, верно, спасибо.

Но, к сожалению, получаю "Cannot perform an aggregate function on an expression containing an aggregate or a subquery.", т.к. Q - достаточно сложное условие с подзапросами.

alexeyvg,
насчет TOP 2 - не понимаю. Мы ж так отсекаем записи, для которых Q может быть истиной.
30 окт 09, 21:56    [7865123]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить