powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Спор про EXISTS
25 сообщений из 33, страница 1 из 2
Спор про EXISTS
    #39966323
Фотография Аленочка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Коллеги, добрый день!

Возник у нас тут спор с командой как всё-таки правильнее проверять наличие данных через EXISTS.
Варианты:

1) WHERE EXISTS (SELECT * FROM..) - больше склоняюсь к этому варианту
2) WHERE EXISTS (SELECT TOP 1 1 FROM..) - в большинстве процедур сейчас по факту используется этот
2) WHERE EXISTS (SELECT 1 FROM..)

Текст по этому поводу из книги T-SQL Fundamentals - 3rd Edition (2016) прилагаю в файле.

Как обычно пишите вы, почему и может у кого-то есть дельные ссылки на исследования по этому поводу?


-----------------------------------------------
А мы тут плюшками балуемся...

Аленочка тм
...
Рейтинг: 0 / 0
Спор про EXISTS
    #39966329
Фотография Ennor Tiegael
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Аленочка,

Код: sql
1.
where exists (select 0 from ...)

TOP избыточен, потому что оптимизатор достаточно умен и де-факто использует его сам.

А звездочка неудобна по двум причинам:
  • Вы не можете использовать такой код с опцией WITH SCHEMABINDING;
  • Если когда-нибудь дело дойдет до рефакторинга / оптимизации, вы можете захотеть переделать все звездные селекты на явные списки полей. Я сталкивался с такой ситуацией, когда SSDT уходил в себя минут на 10-15 при попытке сделать "Find All References" для таблицы, вьюхи или столбца из-за того, что было несколько уровней вложенности вьюх со звездными селектами в них. В этом случае поиск символа * по коду даст вам слишком много false positives на таких местах. Ну т.е. совсем без мусора обойтись не получится, например count(*) по-любому будет влезать, но там можно хотя бы поисковый регэксп в Студии сделать, чтобы игнорировал звездочки внутри скобок. А вот EXISTS * даст вам гору лишнего мусора, в которой придется долго и нудно копать руками.
...
Рейтинг: 0 / 0
Спор про EXISTS
    #39966330
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да все как обычно - план запроса смотришь и убеждаешься что он (скорее всего) один и тот же.
...
Рейтинг: 0 / 0
Спор про EXISTS
    #39966332
PizzaPizza
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А что у вас планы говорят?

У меня при всех вариантах в подзапросе выполняется Row Count Spool на dummy data
...
Рейтинг: 0 / 0
Спор про EXISTS
    #39966333
old_joy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Аленочка,

автор1) WHERE EXISTS (SELECT * FROM..) - больше склоняюсь к этому варианту
Процедуры и функции при обращении к ним компилируются и висят в оперативке. Если там есть подобный подзапрос, то символ * заменяется при этом списком полей.
При изменениях структуры базы могут возникнуть проблемы с возвратом списка полей на *. Придется отследить каждую процедуру со *, сделать в ней изменения и сохранить, чтобы она заново скомпилировалась. Или тормознуть и запустить сервер.

автор1) WHERE EXISTS (SELECT * FROM..) - больше склоняюсь к этому варианту
3) WHERE EXISTS (SELECT 1 FROM..)
Если подзапрос вернет более одной строки - могут быть проблемы.

автор2) WHERE EXISTS (SELECT TOP 1 1 FROM..) - в большинстве процедур сейчас по факту используется этот
Подзапрос всегда вернет только одну строку, не обращаясь к списку полей.
...
Рейтинг: 0 / 0
Спор про EXISTS
    #39966337
Фотография court
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
old_joy
автор1) WHERE EXISTS (SELECT * FROM..) - больше склоняюсь к этому варианту
3) WHERE EXISTS (SELECT 1 FROM..)

Если подзапрос вернет более одной строки - могут быть проблемы.какие ?
...
Рейтинг: 0 / 0
Спор про EXISTS
    #39966339
Фотография Ennor Tiegael
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
old_joy
Или тормознуть и запустить сервер.
Че? Гильотина как средство от головной боли?

И кстати это не поможет, нужен вызов sp_refreshview / sp_refreshsqlmodule. Тот же SSDT вставляет их автоматически в deployment script, если замечает подобные зависимости.
...
Рейтинг: 0 / 0
Спор про EXISTS
    #39966350
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
О! Очередной заруб за exists. Нет чтобы тупо зачитать документацию Microsoft.

Код: sql
1.
 WHERE EXISTS (SELECT * FROM..) 


часть кляузы SELECT ... до FROM в операторе exists НЕ используется.
Т.е. присутствует только для красоты.
Это официально документировано.

Соответственно абсолютно фиолетово чего вы там напишете.

ЗЫ. Справедливости ради надо сказать, что гуру T-SQL придумали таки ситуацию, когда EXISTS (SELECT * FROM...) со звездочкой вызывает проблемы.
Но я, на память, воспроизвести не могу. Это что-то ужасно экзотическое.
...
Рейтинг: 0 / 0
Спор про EXISTS
    #39966362
Фотография a_voronin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Аленочка

2) WHERE EXISTS (SELECT TOP 1 1 FROM..) - в большинстве процедур сейчас по факту используется этот


Используйте и парьтесь.
...
Рейтинг: 0 / 0
Спор про EXISTS
    #39966365
Фотография Ennor Tiegael
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aleks222
ЗЫ. Справедливости ради надо сказать, что гуру T-SQL придумали таки ситуацию, когда EXISTS (SELECT * FROM...) со звездочкой вызывает проблемы.
Но я, на память, воспроизвести не могу. Это что-то ужасно экзотическое.
with schemabinding, я выше писал.
...
Рейтинг: 0 / 0
Спор про EXISTS
    #39966382
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ennor Tiegael
aleks222
ЗЫ. Справедливости ради надо сказать, что гуру T-SQL придумали таки ситуацию, когда EXISTS (SELECT * FROM...) со звездочкой вызывает проблемы.
Но я, на память, воспроизвести не могу. Это что-то ужасно экзотическое.
with schemabinding, я выше писал.


Ну, я и говорил: редкостная экзотика.
Причем компилятор ругнется в этом случае.
...
Рейтинг: 0 / 0
Спор про EXISTS
    #39966383
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
old_joy
Подзапрос всегда вернет только одну строку, не обращаясь к списку полей.

Ничего он никуда не вернет. Сообщением выше твоего уже написали, что в плане там всегда Row Count Spool. Я подозреваю, даже, что если EXISTS переписать через ANY/SOME, то оптимизатор и с этим справится.
...
Рейтинг: 0 / 0
Спор про EXISTS
    #39966390
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aleks222
гуру T-SQL придумали таки ситуацию, когда EXISTS (SELECT * FROM...) со звездочкой вызывает проблемы

Безотносительно что считают гуру моё мнение - звёздочки это зло!
В новых версиях SQL я бы ввел опциональное отключение возможности писать так в запросах.
Генерировать ошибку.

В Оракле, например, с 12 (кажется) версии появилось ограничение на число полей в 1000.
У нас куча запросов со звездочками сломалось, пришлось все править.
...
Рейтинг: 0 / 0
Спор про EXISTS
    #39966393
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL2008
aleks222
гуру T-SQL придумали таки ситуацию, когда EXISTS (SELECT * FROM...) со звездочкой вызывает проблемы

Безотносительно что считают гуру моё мнение - звёздочки это зло!
В новых версиях SQL я бы ввел опциональное отключение возможности писать так в запросах.
Генерировать ошибку.

В Оракле, например, с 12 (кажется) версии появилось ограничение на число полей в 1000.
У нас куча запросов со звездочками сломалось, пришлось все править.

В оракеле сломались запросы, но осудим мы * в MS SQL.
Л - логика.

Есть стандарт SQL он предписывает * в exists.
И нефиг валить с больной головы.
...
Рейтинг: 0 / 0
Спор про EXISTS
    #39966397
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aleks222
Есть стандарт SQL он предписывает * в exists.
И нефиг валить с больной головы.

Как показывает мой опыт (извините, другого нет!) MS идет по стопам ORACLE с задержкой лет 5-7.
Не являюсь сторонником второго, скорее первого. Просто констатирую факт.
Но спорить с вами не буду.
Лень.
Всем удачных выходных!
...
Рейтинг: 0 / 0
Спор про EXISTS
    #39966423
Фотография a_voronin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL2008
aleks222
Есть стандарт SQL он предписывает * в exists.
И нефиг валить с больной головы.

Как показывает мой опыт (извините, другого нет!) MS идет по стопам ORACLE с задержкой лет 5-7.
Не являюсь сторонником второго, скорее первого. Просто констатирую факт.
Но спорить с вами не буду.
Лень.
Всем удачных выходных!


Ну, PIVOT появился в MSSQL раньше Oracle, а вот RANGE BETWEEN INTERVAL из ORACLE все никак не сделают -- отставание более 10 лет.
...
Рейтинг: 0 / 0
Спор про EXISTS
    #39966453
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Аленочка,

Вообще звездочка, но, чтобы сотрудники друг другу горло не грызли, примите волевое решение и документируйте правила написания кода. Звездочка выглядит эстетичнее, тем не менее.

Причем здесь вообще Оракл, почему с ним сравнения? Оракл совершенно другая СУБД и PL/SQL близко не похож на T-SQL. Диаметрально противоположные концепции.
...
Рейтинг: 0 / 0
Спор про EXISTS
    #39966458
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL2008
В Оракле, например, с 12 (кажется) версии появилось ограничение на число полей в 1000.
У нас куча запросов со звездочками сломалось, пришлось все править.

Хм.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
SQL*Plus: Release 11.2.0.1.0 Production on Fri Jun 5 14:06:15 2020

Copyright (c) 1982, 2010, Oracle.  All rights reserved.


Connected to:
Oracle Database 18c Standard Edition 2 Release 18.0.0.0.0 - Production

SQL> select count(*) from dba_tab_columns where owner='SYS' and table_name='ROPP$X$KCVDF';

  COUNT(*)
----------
       150

SQL> select *
  2  from
  3  sys.ROPP$X$KCVDF t1,
  4  sys.ROPP$X$KCVDF t2,
  5  sys.ROPP$X$KCVDF t3,
  6  sys.ROPP$X$KCVDF t4,
  7  sys.ROPP$X$KCVDF t5,
  8  sys.ROPP$X$KCVDF t6,
  9  sys.ROPP$X$KCVDF t7;

no rows selected

SQL> select banner from v$version where banner like 'Ora%';

BANNER
--------------------------------------------------------------------------------
Oracle Database 18c Standard Edition 2 Release 18.0.0.0.0 - Production

150*7=1050. Проверял и на таблицах, в которых есть данные - всё нормально селектится. Скорее всего, это был баг одной из версий оракла, который в следующей версии поправили.
...
Рейтинг: 0 / 0
Спор про EXISTS
    #39966515
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры Павловны
150*7=1050. Проверял и на таблицах, в которых есть данные - всё нормально селектится. Скорее всего, это был баг одной из версий оракла, который в следующей версии поправили.

Возможно, что речь шла именно об уникальных названиях полей.
А тут 7 наборов повторяющихся полей.
Не точно не помню, не буду врать.
...
Рейтинг: 0 / 0
Спор про EXISTS
    #39966516
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну вот же - The absolute maximum number of columns in a table is 1000.
Я был прав. Мы тогда запарились править запросы.
...
Рейтинг: 0 / 0
Спор про EXISTS
    #39966520
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В скуле чуть полегче, но тоже есть ограничения
Columns per table 1,024

Своего мнения не изменил, звездочки это зло!
Разве только исключая конструкцию создания копии таблицы

Код: sql
1.
2.
3.
SELECT *
INTO newTable
FROM oldTable
...
Рейтинг: 0 / 0
Спор про EXISTS
    #39966544
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я даже скажу больше

иногда exists (select 1 ...) хуже чем exists (select filed ....)


Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
create table dbo.a (
	a int
	, b int
)
go

create user testuser without login
go 

grant select on dbo.a to testuser

deny select on dbo.a(b) to testuser
go

execute as user = 'testuser'

select 1
where 
	not exists (
		select *
		from dbo.a
	)
/*
Msg 230, Level 14, State 1, Line 16
The SELECT permission was denied on the column 'b' of the object 'a', database 'test', schema 'dbo'.
*/

select 2
where 
	not exists (
		select a
		from dbo.a
	)
/*
(1 row affected)
*/


select 3
where 
	not exists (
		select 1
		from dbo.a
	)
/*
Msg 230, Level 14, State 1, Line 16
The SELECT permission was denied on the column 'b' of the object 'a', database 'test', schema 'dbo'.
*/

revert
go

drop table dbo.a
drop user testuser
...
Рейтинг: 0 / 0
Спор про EXISTS
    #39966558
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
msLex, получается, что
Код: sql
1.
2.
3.
4.
5.
6.
select 3
where 
	not exists (
		select 1
		from dbo.a
	)


все равно неявно вытаскивает все поля (спасибо msLex), но ломается на заденайеном поле?
Спасибо, этого я не знал.
...
Рейтинг: 0 / 0
Спор про EXISTS
    #39966562
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL2008
все равно неявно вытаскивает все строки поля , но ломается на заденайеном поле?
...
Рейтинг: 0 / 0
Спор про EXISTS
    #39966566
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
msLex,

любопытно, без использования олицетворения это было бы архитектурной ошибкой.
Также представляет интерес:

Код: sql
1.
2.
3.
4.
5.
6.
7.
select 2
where 
	not exists (
		select a
		from dbo.a
		where a.b = 1
	)
...
Рейтинг: 0 / 0
25 сообщений из 33, страница 1 из 2
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Спор про EXISTS
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]