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

Возник у нас тут спор с командой как всё-таки правильнее проверять наличие данных через 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
05.06.2020, 06:39
    #39966329
Ennor Tiegael
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Спор про EXISTS
Аленочка,

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

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

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

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

автор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
05.06.2020, 06:55
    #39966337
court
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Спор про EXISTS
old_joy
автор1) WHERE EXISTS (SELECT * FROM..) - больше склоняюсь к этому варианту
3) WHERE EXISTS (SELECT 1 FROM..)

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

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

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


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

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

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

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


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


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

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

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

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

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

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

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

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

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

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


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

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

Причем здесь вообще Оракл, почему с ним сравнения? Оракл совершенно другая СУБД и PL/SQL близко не похож на T-SQL. Диаметрально противоположные концепции.
...
Рейтинг: 0 / 0
05.06.2020, 12:11
    #39966458
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Спор про EXISTS
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
05.06.2020, 14:26
    #39966515
SQL2008
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Спор про EXISTS
Сон Веры Павловны
150*7=1050. Проверял и на таблицах, в которых есть данные - всё нормально селектится. Скорее всего, это был баг одной из версий оракла, который в следующей версии поправили.

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

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

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

иногда 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
05.06.2020, 15:59
    #39966558
SQL2008
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Спор про EXISTS
msLex, получается, что
Код: sql
1.
2.
3.
4.
5.
6.
select 3
where 
	not exists (
		select 1
		from dbo.a
	)


все равно неявно вытаскивает все поля (спасибо msLex), но ломается на заденайеном поле?
Спасибо, этого я не знал.
...
Рейтинг: 0 / 0
05.06.2020, 16:02
    #39966562
msLex
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Спор про EXISTS
SQL2008
все равно неявно вытаскивает все строки поля , но ломается на заденайеном поле?
...
Рейтинг: 0 / 0
05.06.2020, 16:07
    #39966566
Владислав Колосов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Спор про EXISTS
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
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Спор про EXISTS / 25 сообщений из 33, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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