Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Как лучше писать когда нужен exists(...where ...) OR (вообще пусто)  [new]
Onax
Member

Откуда:
Сообщений: 23
Можно ли это написать лучше?
в словах запрос звучит так: выбрать группы, у которых есть любые страны кроме (1,2,3) ИЛИ нет стран вообще

                   AND (EXISTS
                           (
                               SELECT 1
                               FROM dbo.GroupCountry g
                               WHERE g.CountryId <> 179
                                     AND g.CountryId <> 113
                                     AND g.CountryId <> 225
                                     AND g.groupid = f.id
                           )
                            OR (NOT EXISTS
                               (
                                   SELECT 1
                                   FROM dbo.GroupCountry g
                                   WHERE g.groupid = f.id
                               )))
19 ноя 16, 17:43    [19911826]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше писать когда нужен exists(...where ...) OR (вообще пусто)  [new]
aleks2
Guest
а чо, просто

and
not exists( select * from dbo.GroupCountry where CountryId in (1,2,3) and groupid = f.id )


не канает?
19 ноя 16, 18:08    [19911864]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше писать когда нужен exists(...where ...) OR (вообще пусто)  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
aleks2
а чо, просто

and
not exists( select * from dbo.GroupCountry where CountryId in (1,2,3) and groupid = f.id )



не канает?
Если есть CountryId = 1, то обязательно должна быть запись CountryId not in (1,2,3)
А это условие такой случай отбросит.
То есть, (1,2,3) допустимы, но в случае, когда есть что-то ещё.
19 ноя 16, 18:13    [19911880]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше писать когда нужен exists(...where ...) OR (вообще пусто)  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Я думаю, в первом посте всё написано правильно.
Разве что есть лишние скобки
и вместо трёх условий <> можно написать NOT IN()
19 ноя 16, 18:16    [19911885]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше писать когда нужен exists(...where ...) OR (вообще пусто)  [new]
Fungus
Member

Откуда:
Сообщений: 63
aleks2
а чо, просто

and
not exists( select * from dbo.GroupCountry where CountryId in (1,2,3) and groupid = f.id )


не канает?


Офтопик.
Подтвердите мою догадку, что так выйдет быстрее:
not exists( select top(1)1 from dbo.GroupCountry where CountryId in (1,2,3) and groupid = f.id )


Так не будет считывания полей таблицы (только те, что участвуют в where) + запрос остановится после нахождения первой подходящей строки. Если написать просто "select 1", я так понимаю, запрос пройдет по все таблице или все же остановится при нахождении первой же записи ?
21 ноя 16, 18:56    [19917945]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше писать когда нужен exists(...where ...) OR (вообще пусто)  [new]
Добрый Э - Эх
Guest
Fungus,

Быстрее всего будет, если в селект-листе [not]exists-подзапроса писать 1/0. :)
Ни звездочка, ни топ1 1 не дадут такого прироста скорости выполнения запроса.
21 ноя 16, 19:08    [19917971]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше писать когда нужен exists(...where ...) OR (вообще пусто)  [new]
aleks2
Guest
Fungus
aleks2
а чо, просто

and
not exists( select * from dbo.GroupCountry where CountryId in (1,2,3) and groupid = f.id )


не канает?


Офтопик.
Подтвердите мою догадку, что так выйдет быстрее:
not exists( select top(1)1 from dbo.GroupCountry where CountryId in (1,2,3) and groupid = f.id )


Так не будет считывания полей таблицы (только те, что участвуют в where) + запрос остановится после нахождения первой подходящей строки. Если написать просто "select 1", я так понимаю, запрос пройдет по все таблице или все же остановится при нахождении первой же записи ?


Вы бредите. Абсолютно пофиг, что написано в списке select под exists.
21 ноя 16, 19:18    [19917998]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше писать когда нужен exists(...where ...) OR (вообще пусто)  [new]
Fungus
Member

Откуда:
Сообщений: 63
aleks2,

Ошибаетесь :) Как раз в exist категорически нельзя указывать поля в селекте. Так они будут считываться из таблицы, что совершенно излишне.

У меня вопрос лишь о том, писать ли просто 1 или лучше top(1)1.
21 ноя 16, 19:31    [19918033]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше писать когда нужен exists(...where ...) OR (вообще пусто)  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Fungus
aleks2,

Ошибаетесь :) Как раз в exist категорически нельзя указывать поля в селекте. Так они будут считываться из таблицы, что совершенно излишне..
Приведите хотя бы один план выполнения, который подтверждает ваше заявление.
21 ноя 16, 19:32    [19918036]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше писать когда нужен exists(...where ...) OR (вообще пусто)  [new]
Fungus
Member

Откуда:
Сообщений: 63
Добрый Э - Эх
select top(1) 1 не даст прироста по сравнению с select 1


Почему ?
21 ноя 16, 19:33    [19918042]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше писать когда нужен exists(...where ...) OR (вообще пусто)  [new]
Верблюд
Member

Откуда: Яженичеловек!!!
Сообщений: 65007
Fungus
aleks2,

Ошибаетесь :) Как раз в exist категорически нельзя указывать поля в селекте. Так они будут считываться из таблицы, что совершенно излишне.

У меня вопрос лишь о том, писать ли просто 1 или лучше top(1)1.


Писать *. И да, в exists как раз все поля игнорируются, можете планы выполнения посмотреть.
21 ноя 16, 19:35    [19918050]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше писать когда нужен exists(...where ...) OR (вообще пусто)  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Гавриленко Сергей Алексеевич
Fungus
aleks2,

Ошибаетесь :) Как раз в exist категорически нельзя указывать поля в селекте. Так они будут считываться из таблицы, что совершенно излишне..
Приведите хотя бы один план выполнения, который подтверждает ваше заявление.

Да и вообще:

https://technet.microsoft.com/en-us/library/ms189259.aspx?ppud=4
The select list of a subquery introduced by EXISTS almost always consists of an asterisk (*). There is no reason to list column names because you are just testing whether rows that meet the conditions specified in the subquery exist.
21 ноя 16, 19:39    [19918058]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше писать когда нужен exists(...where ...) OR (вообще пусто)  [new]
Fungus
Member

Откуда:
Сообщений: 63
Да похоже так. Планы вышли идентичными.
Зачем я все время писал select 1 в exist остается загадкой (для меня), фиг знает откуда почерпнул эту оптимизацию. Теперь не буду :)
21 ноя 16, 19:42    [19918064]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше писать когда нужен exists(...where ...) OR (вообще пусто)  [new]
Верблюд
Member

Откуда: Яженичеловек!!!
Сообщений: 65007
Fungus
Добрый Э - Эх
select top(1) 1 не даст прироста по сравнению с select 1


Почему ?


Потому что exists и так будет ждать одну запись.
21 ноя 16, 19:42    [19918065]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше писать когда нужен exists(...where ...) OR (вообще пусто)  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Однако, если в списке SELECT будут поля, это вынудит проверять наличие этих полей и права доступа к ним
21 ноя 16, 19:57    [19918109]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше писать когда нужен exists(...where ...) OR (вообще пусто)  [new]
Fungus
Member

Откуда:
Сообщений: 63
Верблюд
Fungus
пропущено...


Почему ?


Потому что exists и так будет ждать одну запись.


Ну мало ли, что он ждет одну запись. А мы ему все дадим :)
Однако что select *, что select 1, что top(1)1 выдали идентичные планы. Для меня это загадка. SQL сервер сознательно игнорирует и не делает выборку полей из select + берет только первую строку, несмотря на то, что мы ему указываем ?
21 ноя 16, 20:11    [19918156]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше писать когда нужен exists(...where ...) OR (вообще пусто)  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Fungus
Верблюд
пропущено...


Потому что exists и так будет ждать одну запись.


Ну мало ли, что он ждет одну запись. А мы ему все дадим :)
Однако что select *, что select 1, что top(1)1 выдали идентичные планы. Для меня это загадка. SQL сервер сознательно игнорирует и не делает выборку полей из select + берет только первую строку, несмотря на то, что мы ему указываем ?
Зачем для exists брать более одной строки?
21 ноя 16, 20:12    [19918158]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше писать когда нужен exists(...where ...) OR (вообще пусто)  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
Гавриленко Сергей Алексеевич
Fungus
пропущено...


Ну мало ли, что он ждет одну запись. А мы ему все дадим :)
Однако что select *, что select 1, что top(1)1 выдали идентичные планы. Для меня это загадка. SQL сервер сознательно игнорирует и не делает выборку полей из select + берет только первую строку, несмотря на то, что мы ему указываем ?
Зачем для exists брать более одной строки?

человек утверждал глупость, теперь пытается шуточками придумать глупости оправдание...
21 ноя 16, 20:15    [19918170]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше писать когда нужен exists(...where ...) OR (вообще пусто)  [new]
andrey odegov
Member

Откуда:
Сообщений: 473
Добрый Э - Эх
Fungus,

Быстрее всего будет, если в селект-листе [not]exists-подзапроса писать 1/0. :)
Ни звездочка, ни топ1 1 не дадут такого прироста скорости выполнения запроса.
это точно :)
select top 1 @@version
from master..spt_values
where exists(select 1/0)
И Oracle об этом тоже знает
select banner as "oracle version"
from v$version
where exists(select 1/0 from dual)
21 ноя 16, 20:20    [19918182]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше писать когда нужен exists(...where ...) OR (вообще пусто)  [new]
Fungus
Member

Откуда:
Сообщений: 63
TaPaK
Гавриленко Сергей Алексеевич
пропущено...
Зачем для exists брать более одной строки?

человек утверждал глупость, теперь пытается шуточками придумать глупости оправдание...


Найн! Было сказано, что exist ждет одну строку а я ответил, что мало ли, что он там ждет - мы ему дадим больше чем он ждет. Чисто программистская логика, в попытках откопать баг.
И дальше написал, что интересно получается, что exist сам сознательно игнорит поля, указанные в select.
21 ноя 16, 20:26    [19918202]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше писать когда нужен exists(...where ...) OR (вообще пусто)  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Fungus
TaPaK
пропущено...

человек утверждал глупость, теперь пытается шуточками придумать глупости оправдание...


Найн! Было сказано, что exist ждет одну строку а я ответил, что мало ли, что он там ждет - мы ему дадим больше чем он ждет. Чисто программистская логика, в попытках откопать баг.
И дальше написал, что интересно получается, что exist сам сознательно игнорит поля, указанные в select.
Не игнорит, а оптимизирует.
21 ноя 16, 20:28    [19918205]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше писать когда нужен exists(...where ...) OR (вообще пусто)  [new]
andrey odegov
Member

Откуда:
Сообщений: 473
Fungus
Верблюд
пропущено...


Потому что exists и так будет ждать одну запись.


Ну мало ли, что он ждет одну запись. А мы ему все дадим :)
Однако что select *, что select 1, что top(1)1 выдали идентичные планы. Для меня это загадка. SQL сервер сознательно игнорирует и не делает выборку полей из select + берет только первую строку, несмотря на то, что мы ему указываем ?
это следует из логической обработки запросов (тут на английском). если после from и where есть строка, то зачем продолжать дальше?
21 ноя 16, 20:28    [19918206]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше писать когда нужен exists(...where ...) OR (вообще пусто)  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
Fungus
TaPaK
пропущено...

человек утверждал глупость, теперь пытается шуточками придумать глупости оправдание...


Найн! Было сказано, что exist ждет одну строку а я ответил, что мало ли, что он там ждет - мы ему дадим больше чем он ждет. Чисто программистская логика, в попытках откопать баг.
И дальше написал, что интересно получается, что exist сам сознательно игнорит поля, указанные в select.
ппц, ждё, дадим... столовая какая-то. Скл не такой тупой как.. он понимает что на вопрос "существуют ли Валеры в телефонном справочнике" надо увидеть только одного Валеру и не орать сотню раз Ваалера и да всё равно как вы подтверите наличие Валеры в справочнике хоть Да, хоть 1
21 ноя 16, 20:31    [19918213]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше писать когда нужен exists(...where ...) OR (вообще пусто)  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
В конце концов, заставить сервер работать по идее можно через ( select count(*) from... ) > 0.
21 ноя 16, 20:36    [19918221]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше писать когда нужен exists(...where ...) OR (вообще пусто)  [new]
aleks2
Guest
Прикола ради, список из select влияет таки
declare @t table(i int);

insert @t values(1);

select * from @t where exists( select * from @t);

select * from @t where exists( select top(0) * from @t);
21 ноя 16, 20:38    [19918225]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить