Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Что быстрее?  [new]
R-Magistr
Member

Откуда:
Сообщений: 356
Здравствуйте
Я начинающий, и среди моих учителей есть разные мнения, вот я решил спросить у настоящих знатоков:
пример запроса
select perem1 from table1
и тут надо поставить условие что бы не вываливались значения где perem1 является NULL
Что же работает быстрее?
такой пример -
select perem1 from table1 where perem1 is not null

или такой пример -
select perem1 from table1 where isnull(perem1 ,0)<>0

когдя я начинал читать книжки для начинающих по sql там везде приводились примеры на первый вариант, но мои гуру говорят что надо писать второй вариант, я конечно гуру слушаю, но для себя хотелось бы выяснить чтож таки быстрее работает?
30 мар 14, 10:39    [15806866]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее?  [new]
invm
Member

Откуда: Москва
Сообщений: 9827
Поменяйте гуру, ибо они не гуру. Либо вы их не понимаете.
Почитайте лучше про sargable predicates

В вашем конкретном случае, второй запрос всегда приводит к сканированию всей таблицы, первый же можно оптимизировать созданием индекса по perem1.
30 мар 14, 11:12    [15806900]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее?  [new]
invm
Member

Откуда: Москва
Сообщений: 9827
Более того, второй запрос вообще неверен, если в perem1 допустимы нули.
30 мар 14, 11:17    [15806912]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее?  [new]
R-Magistr
Member

Откуда:
Сообщений: 356
invm
Более того, второй запрос вообще неверен, если в perem1 допустимы нули.

ну во втором запросе говорят что типо если в perem1 null, то менять его на 0 и потом сравнивать с 0, а так как стоит <> 0 (не равно с 0), то значит что если perem1 является null,то эта строка не отобразится, что и в первом примере, но вот только что работает быстрее
30 мар 14, 11:28    [15806925]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее?  [new]
R-Magistr
Member

Откуда:
Сообщений: 356
invm
Поменяйте гуру, ибо они не гуру. Либо вы их не понимаете.
Почитайте лучше про sargable predicates

В вашем конкретном случае, второй запрос всегда приводит к сканированию всей таблицы, первый же можно оптимизировать созданием индекса по perem1.


Короче проверили на оптимизаторе, и второй вариант гораздо быстрее в несколько десятков раз
30 мар 14, 11:40    [15806943]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее?  [new]
invm
Member

Откуда: Москва
Сообщений: 9827
R-Magistr,

create table #t (p int null);
go

insert into #t
select top (1000000)
 case when row_number() over (order by char('a')) % 10 = 0 then null else rand(checksum(newid())) * 100 + 1 end
from
 master.dbo.spt_values a cross join
 master.dbo.spt_values b;
go

set statistics time on;

select count(*) from #t where p is not null;
select count(*) from #t where isnull(p, 0) <> 0;

set statistics time off;
go

drop table #t;
go
Сможете исправить приведенный скрипт так, чтобы продемонстрировать
R-Magistr
второй вариант гораздо быстрее в несколько десятков раз
?

И как вы собираетесь учитывать 15806912?
30 мар 14, 12:36    [15807028]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее?  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 6201
R-Magistr
проверили на оптимизаторе

Это как, пардон?
30 мар 14, 13:10    [15807096]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее?  [new]
R-Magistr
Member

Откуда:
Сообщений: 356
Сон Веры Павловны
R-Magistr
проверили на оптимизаторе

Это как, пардон?

на сайте sql-ex.ru есть аптимизатор, вот там составили одинаковые запросы и с тем и с тем предикатом, и посмотрели
30 мар 14, 15:14    [15807294]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее?  [new]
R-Magistr
Member

Откуда:
Сообщений: 356
invm
R-Magistr,

create table #t (p int null);
go

insert into #t
select top (1000000)
 case when row_number() over (order by char('a')) % 10 = 0 then null else rand(checksum(newid())) * 100 + 1 end
from
 master.dbo.spt_values a cross join
 master.dbo.spt_values b;
go

set statistics time on;

select count(*) from #t where p is not null;
select count(*) from #t where isnull(p, 0) <> 0;

set statistics time off;
go

drop table #t;
go
Сможете исправить приведенный скрипт так, чтобы продемонстрировать
R-Magistr
второй вариант гораздо быстрее в несколько десятков раз
?

И как вы собираетесь учитывать 15806912?


так вроде там и стоит проверка на null, или я вас не понял, разжуйте пожалуйста, я новичёк
30 мар 14, 15:16    [15807302]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее?  [new]
qwrqwr
Member

Откуда: Msk
Сообщений: 1684
R-Magistr
на сайте sql-ex.ru есть аптимизатор,

А внутре него неонка (с)
30 мар 14, 15:39    [15807348]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее?  [new]
Гуест12345
Guest
R-Magistr
на сайте sql-ex.ru есть аптимизатор, вот там составили одинаковые запросы и с тем и с тем предикатом, и посмотрели

Это вам гуры так посоветовали проверять оптимальность запроса?
Это убиться об стену просто, какой замечательный тест.

Вы создайте реальные таблицы на реально сервере и посмотрите планы выполнения запросов, чтения, CPU.
30 мар 14, 16:40    [15807523]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31951
R-Magistr
так вроде там и стоит проверка на null, или я вас не понял, разжуйте пожалуйста, я новичёк
Вам говорят не о допустимости значения NULL, а о допустимости значения 0

Вот у вас есть значения:

NULL
0
1
2
3

Первый запрос выведет 4 записи, второй 3.
Так что запросы не одинаковые по выдаваемому результату, а не только по быстродействию.
30 мар 14, 18:04    [15807771]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее?  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
R-Magistr
Сон Веры Павловны
пропущено...

Это как, пардон?

на сайте sql-ex.ru есть аптимизатор, вот там составили одинаковые запросы и с тем и с тем предикатом, и посмотрели
Вы бы еще на кофейной гуще погадали.
31 мар 14, 02:20    [15809064]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее?  [new]
R-Magistr
Member

Откуда:
Сообщений: 356
alexeyvg
R-Magistr
так вроде там и стоит проверка на null, или я вас не понял, разжуйте пожалуйста, я новичёк
Вам говорят не о допустимости значения NULL, а о допустимости значения 0

Вот у вас есть значения:

NULL
0
1
2
3

Первый запрос выведет 4 записи, второй 3.
Так что запросы не одинаковые по выдаваемому результату, а не только по быстродействию.


У меня задача, где мне 0 то же не нужен:
чем
where perem is not null and perem<>0

лучше один раз написать
isnull(perem,0)<>0

Или я ошибаюсь? Знатоки поправьте меня пожалуйста, если я не прав ((
2 апр 14, 09:17    [15819551]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее?  [new]
Glory
Member

Откуда:
Сообщений: 104751
R-Magistr
лучше один раз написать

Лучше кому ?
2 апр 14, 09:18    [15819556]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее?  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
R-Magistr
alexeyvg
пропущено...
Вам говорят не о допустимости значения NULL, а о допустимости значения 0

Вот у вас есть значения:

NULL
0
1
2
3

Первый запрос выведет 4 записи, второй 3.
Так что запросы не одинаковые по выдаваемому результату, а не только по быстродействию.


У меня задача, где мне 0 то же не нужен:
чем
where perem is not null and perem<>0


лучше один раз написать
isnull(perem,0)<>0


Или я ошибаюсь? Знатоки поправьте меня пожалуйста, если я не прав ((
Все эти условия в WHERE эквивалентны такому:
WHERE perem<>0
и всё!
2 апр 14, 09:22    [15819572]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее?  [new]
R-Magistr
Member

Откуда:
Сообщений: 356
iap
R-Magistr
пропущено...


У меня задача, где мне 0 то же не нужен:
чем
where perem is not null and perem<>0


лучше один раз написать
isnull(perem,0)<>0


Или я ошибаюсь? Знатоки поправьте меня пожалуйста, если я не прав ((
Все эти условия в WHERE эквивалентны такому:
WHERE perem<>0
и всё!


тогда придётся писать два условия:
where perem<>0 and perem is not null

когда можно один раз
where isnull(perem,0)<>0
4 апр 14, 07:23    [15830941]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее?  [new]
Ennor Tiegael
Member

Откуда:
Сообщений: 3422
R-Magistr
тогда придётся писать два условия:
where perem<>0 and perem is not null
Не придется. Попробуйте сами проверить, это несложно.

Только убедитесь, что у вас в соединении стоит
set ansi_nulls on;
4 апр 14, 07:59    [15830976]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее?  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Ennor Tiegael
R-Magistr
тогда придётся писать два условия:
where perem<>0 and perem is not null

Не придется. Попробуйте сами проверить, это несложно.

Только убедитесь, что у вас в соединении стоит
set ansi_nulls on;
SET ANSI_NULLS OFF;
DECLARE @T TABLE(F INT NULL);
INSERT @T(F) VALUES(0),(NULL),(1);
SELECT * FROM @T WHERE F<>0;
ANSI_NULLS влияет на явное сравнение с литеральным NULL
4 апр 14, 09:19    [15831143]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее?  [new]
Ennor Tiegael
Member

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

Я на всякий случай это упомянул. Кроме того, вангую, рано или поздно вместо литерального нуля там появится переменная, и вот тогда с этой опцией жизнь внезапно заиграет новыми красками.

Microsoft давно уже пора убрать эту настройку вообще, как они давно обещают...
4 апр 14, 09:41    [15831230]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее?  [new]
R-Magistr
Member

Откуда:
Сообщений: 356
Ennor Tiegael
R-Magistr
тогда придётся писать два условия:
where perem<>0 and perem is not null
Не придется. Попробуйте сами проверить, это несложно.

Только убедитесь, что у вас в соединении стоит
set ansi_nulls on;


Что-то не догоню, почему не придется писать два условия?
4 апр 14, 13:18    [15832713]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее?  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
R-Magistr
Ennor Tiegael
пропущено...
Не придется. Попробуйте сами проверить, это несложно.

Только убедитесь, что у вас в соединении стоит
set ansi_nulls on;



Что-то не догоню, почему не придется писать два условия?
WHERE <выражение> пропускает только те строки,
для которых <выражение> вернёт TRUE.
Арифметические операторы и операторы сравнения, одним из операндов которых является NULL,
возвращают не TRUE и не FALSE, а третье значение - UNKNOWN ("неизвестно что", короче говоря).
Значит, NULL<>0 вернёт UNKNOWN, в то время как WHERE хочет TRUE.
Следовательно, в этом случае NULL не пройдёт, как и в случае IS NOT NULL.
4 апр 14, 13:24    [15832751]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее?  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
iap
R-Magistr
пропущено...


Что-то не догоню, почему не придется писать два условия?
WHERE <выражение> пропускает только те строки,
для которых <выражение> вернёт TRUE.
Арифметические операторы и операторы сравнения, одним из операндов которых является NULL,
возвращают не TRUE и не FALSE, а третье значение - UNKNOWN ("неизвестно что", короче говоря).
Значит, NULL<>0 вернёт UNKNOWN, в то время как WHERE хочет TRUE.
Следовательно, в этом случае NULL не пройдёт, как и в случае IS NOT NULL.
Кстати, поведение NULL заумно называется "троичная логика"
4 апр 14, 13:25    [15832758]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее?  [new]
R-Magistr
Member

Откуда:
Сообщений: 356
iap
R-Magistr
пропущено...


Что-то не догоню, почему не придется писать два условия?
WHERE <выражение> пропускает только те строки,
для которых <выражение> вернёт TRUE.
Арифметические операторы и операторы сравнения, одним из операндов которых является NULL,
возвращают не TRUE и не FALSE, а третье значение - UNKNOWN ("неизвестно что", короче говоря).
Значит, NULL<>0 вернёт UNKNOWN, в то время как WHERE хочет TRUE.
Следовательно, в этом случае NULL не пройдёт, как и в случае IS NOT NULL.


там стоит проверка на ISNULL, который если таки perem=null, то подставляет 0, и уже 0 сравнивает с 0, и тут нет ни какой ункноу мать его )))))) и троичной логики, мы тут сразу избавляемся от этой троичной логики, вы что не видите что ли что идёт проверка на null и если null, то подставляется 0, и потом дальше идёт уже 0, я же черным по серому (такое оформление в этом форуме) пишу isnull(perem,0)<>0, тут же понятно что если null, то ставить 0, какая тут ещё троичная логика, где вы тут её взяли, тут же подмена идёт если null, то ставим 0, 0 ставим там НОООООООООООЛЬ МЫ ТАМ СТАВИМ ЕСЛИ PEREM=NULL, ПОНЯЛИ?!
4 апр 14, 14:15    [15833070]     Ответить | Цитировать Сообщить модератору
 Re: Что быстрее?  [new]
pegoopik_
Guest
>>НОООООООООООЛЬ МЫ ТАМ СТАВИМ ЕСЛИ PEREM=NULL, ПОНЯЛИ?!

SELECT CASE WHEN perm=NULL THEN 0 ELSE 'не поняли:)' END
FROM(VALUES(null))T(perm)
4 апр 14, 14:24    [15833150]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить