powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / ISNULL() = ISNULL()
19 сообщений из 19, страница 1 из 1
ISNULL() = ISNULL()
    #40072844
Hamber
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
DECLARE @pole1 Varchar(max), @pole2 varchar(max), @pole3 varchar(max)

SELECT id FROM table
WHERE ISNULL(field1, '') = ISNULL(@pole1, '') AND ISNULL(field2, '') = ISNULL(@pole2, '') AND ISNULL(field3, '') = ISNULL(@pole3, '')



Подскажите, как такие запросы переписывать более оптимально и возможно ли?
...
Рейтинг: 0 / 0
ISNULL() = ISNULL()
    #40072845
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дык, не допускать null в ячейке таблицы.
...
Рейтинг: 0 / 0
ISNULL() = ISNULL()
    #40072852
Кесарь
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hamber
Код: sql
1.
2.
3.
4.
DECLARE @pole1 Varchar(max), @pole2 varchar(max), @pole3 varchar(max)

SELECT id FROM table
WHERE ISNULL(field1, '') = ISNULL(@pole1, '') AND ISNULL(field2, '') = ISNULL(@pole2, '') AND ISNULL(field3, '') = ISNULL(@pole3, '')



Подскажите, как такие запросы переписывать более оптимально и возможно ли?


На все три условия лень расписывать (там ведь пересечение вариантов, код пухнет, и вовсе не факт, что в итоге будет быстрее работать), но для одного условия это делается так:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
SELECT id
FROM table
WHERE field1 is not null
  and @pole1 is not null
  and field1 = @pole1

union all

SELECT id
FROM table
WHERE field1 is null
...
Рейтинг: 0 / 0
ISNULL() = ISNULL()
    #40072853
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ну можно так.
Код: sql
1.
2.
3.
4.
DECLARE @pole1 Varchar(max), @pole2 varchar(max), @pole3 varchar(max)

SELECT id FROM table
WHERE exists (Select field1, field2, field3 intersect Select @pole1, @pole2, @pole3 )


но это монопениссуарно.
...
Рейтинг: 0 / 0
ISNULL() = ISNULL()
    #40072991
Oleg_SQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
uaggster,

а если перед селектом выполнить:

Код: sql
1.
2.
3.
SET @pole1 = ISNULL(@pole1,'')
SET @pole2 = ISNULL(@pole2,'')
SET @pole3 = ISNULL(@pole3,'')



то можно

Код: sql
1.
2.
SELECT id FROM table
WHERE ISNULL(field1, '') = @pole1 AND ISNULL(field2, '') = @pole2 AND ISNULL(field3, '') = @pole3
...
Рейтинг: 0 / 0
ISNULL() = ISNULL()
    #40073014
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Oleg_SQL, ну, при этом вы отключите parameter sniffing. Это не безусловно хорошо, и не безусловно плохо, но нужно понимать, что в следствие этого произойдет.
...
Рейтинг: 0 / 0
ISNULL() = ISNULL()
    #40073022
Oleg_SQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
uaggster
Oleg_SQL, ну, при этом вы отключите parameter sniffing. Это не безусловно хорошо, и не безусловно плохо, но нужно понимать, что в следствие этого произойдет.


Речи о ХП не было...

Тогда так?

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
DECLARE @pole1 Varchar(max), @pole2 varchar(max), @pole3 varchar(max);

DECLARE @p1 Varchar(max) = ISNULL(@pole1,''), 
             @p2 varchar(max) = ISNULL(@pole2,''), 
             @p3 varchar(max) = ISNULL(@pole3,'');


SELECT id FROM table
 WHERE ISNULL(field1, '') = @p1 
           AND ISNULL(field2, '') = @p2 
           AND ISNULL(field3, '') = @p3

;
...
Рейтинг: 0 / 0
ISNULL() = ISNULL()
    #40073026
Кесарь
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Oleg_SQL,

это вам мало что даст в плане оптимизации. Хотя конечно для краткости и понятности кода это лучше.

isnull по переменной движком сервера будет определён один раз и далее будет использовано это значение.

А вот isnull по полю будет отрабатывать как раз для каждой строки. Чего и нужно избегать.


Поэтому надо делать так, как я написал выше. Но так как у вас три поля фильтруется с условием по нуллу, то так просто не сделать. Вы не можете сделать два блока, в которых будет не нулл и нулл. Потому что это уже будет другое условие. Ведь каждое поле может принимать значение нулл независимо от остальных.

Значит надо пойти путём разбиения запроса на подзапросы. Надо оценить кол-во данных, которые выдаёт запрос, если условием оставить только одно поле. Затем создать временную таблицу, которую заполнить запросом по тому полю, которое даёт наименьшее кол-во строк. Ессно этот запрос должен выдавать два остальных поля в качестве значений результирующего набора.

Этот запрос делать так, как я указал выше с двумя блоками.

А уже эту временную таблицу фильтровать по оставшимся двум полям не заморачиваясь на оптимизацию и красивости по нуллам.
...
Рейтинг: 0 / 0
ISNULL() = ISNULL()
    #40073036
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кесарь
Поэтому надо делать так, как я написал выше.
Так делать не надо. От слова "совсем".
Кесарь
Значит надо пойти путём разбиения запроса на подзапросы. Надо оценить кол-во данных, которые выдаёт запрос, если условием оставить только одно поле. Затем создать временную таблицу, которую заполнить запросом по тому полю, которое даёт наименьшее кол-во строк. Ессно этот запрос должен выдавать два остальных поля в качестве значений результирующего набора.
И так делать не надо. От слова "совсем".

Делать надо как предложено в 22327012 .
Это, в отличие от ваших монструозных предложений, не только проще и эффективнее, но еще и саргабельно.
...
Рейтинг: 0 / 0
ISNULL() = ISNULL()
    #40073040
Кесарь
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm
Кесарь
Поэтому надо делать так, как я написал выше.
Так делать не надо. От слова "совсем".
Кесарь
Значит надо пойти путём разбиения запроса на подзапросы. Надо оценить кол-во данных, которые выдаёт запрос, если условием оставить только одно поле. Затем создать временную таблицу, которую заполнить запросом по тому полю, которое даёт наименьшее кол-во строк. Ессно этот запрос должен выдавать два остальных поля в качестве значений результирующего набора.
И так делать не надо. От слова "совсем".

Делать надо как предложено в 22327012 .
Это, в отличие от ваших монструозных предложений, не только проще и эффективнее, но еще и саргабельно.


Вопрос был про оптимизацию, а не синтаксический сахар. И сам uaggster, предложивший этот красивый способ, в отличие от вас это понимает.


А почему "не надо" и тем более "от словам совсем", неплохо бы обосновывать.
...
Рейтинг: 0 / 0
ISNULL() = ISNULL()
    #40073075
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кесарь
Вопрос был про оптимизацию, а не синтаксический сахар
Оптимизация - это когда получаем какое-то улучшение по сравнению с исходным решением.

И что же вы наоптимизировали?
У вас же не улучшение, а ухудшение. Причем кратное. И по читабельности, и по производительности, и по трудозатратам.

Кстати, uaggster ошибся написав "но это монопениссуарно". Потому что его вариант саргабельный, в отличие от остальных предложенных.

Ну и на досуге почитайте, что же такое "синтаксический сахар".
...
Рейтинг: 0 / 0
ISNULL() = ISNULL()
    #40073139
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invm

Кстати, uaggster ошибся написав "но это монопениссуарно". Потому что его вариант саргабельный , в отличие от остальных предложенных.

А саргабельный - это как? Нашел только 2 странички с использованием этого слова.
...
Рейтинг: 0 / 0
ISNULL() = ISNULL()
    #40073146
Фотография Shakill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
ISNULL() = ISNULL()
    #40073166
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Shakill, гм... спасибо. Не знал, что для "ускоряется индексами" существует отдельный термин.
...
Рейтинг: 0 / 0
ISNULL() = ISNULL()
    #40073262
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggster
Shakill, гм... спасибо. Не знал, что для "ускоряется индексами" существует отдельный термин.
При чём здесь ускорение? Применимость индексов для запроса.
...
Рейтинг: 0 / 0
ISNULL() = ISNULL()
    #40073398
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
iap
uaggster
Shakill, гм... спасибо. Не знал, что для "ускоряется индексами" существует отдельный термин.
При чём здесь ускорение? Применимость индексов для запроса.

Что значит "применимость"? Любой индекс, содержащий + - нужные поля (в ключевых и include) может быть применен для любого запроса по этим самым полям.
Например - этот индекс может быть просканирован. И кстати, в варианте ТС, если подходящий индекс существует, так и будет, скорее всего, сделано. Не факт, конечно, что индекс по полям field1, field2, field3 может существовать, т.к. он там DECLARE @pole1 Varchar(max) делает, х.з. что из себя field1 представляет. Ну ладно, пусть у него поля там varchar(255) какие-нибудь.
Тогда индекс будет использован и будет сканироваться. И в варианте с intersect, кстати, скорее всего тоже.
Вот пример:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
Create table #t (id int not null identity(1,1) primary key clustered, field1 varchar(255), field2 varchar(255), field3 varchar(255))

;With s as (Select * from (Values (NULL), ('a'), ('b'), ('c'), ('d'), ('e'), ('f'), ('g'), ('h'), ('i')) t(n))
insert into #t (field1, field2, field3)
Select s1.n, s2.n, s3.n from s s1 cross join s s2 cross join s s3 cross join s s4 cross join s s5

Create nonclustered index ix_1 on #t (field1, field2, field3)

DECLARE @pole1 Varchar(max) = 'g', @pole2 varchar(max) = 'a', @pole3 varchar(max) = NULL

SELECT id FROM #t
WHERE ISNULL(field1, '') = ISNULL(@pole1, '') AND ISNULL(field2, '') = ISNULL(@pole2, '') AND ISNULL(field3, '') = ISNULL(@pole3, '')

SELECT id FROM #t
WHERE exists (Select field1, field2, field3 intersect Select @pole1, @pole2, @pole3 )



Так что индекс применим в обоих случаях. :-)
...
Рейтинг: 0 / 0
ISNULL() = ISNULL()
    #40073399
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ситуация, правда, радикально меняется, если не допускать идиотизма, и декларировать переменные правильно:
Код: sql
1.
DECLARE @pole1 Varchar(255) = 'g', @pole2 varchar(255) = 'a', @pole3 varchar(255) = NULL


Тогда индекс не просто используется, но используется максимально эффективно.
...
Рейтинг: 0 / 0
ISNULL() = ISNULL()
    #40073800
Фотография Shakill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggster
iap
пропущено...
При чём здесь ускорение? Применимость индексов для запроса.

Что значит "применимость"? Любой индекс, содержащий + - нужные поля (в ключевых и include) может быть применен для любого запроса по этим самым полям.
Например - этот индекс может быть просканирован


SARGable - SEARCH argument able, это свойство именно предиката. не данных и не фактически имеющихся индексов. имеется в виду, что для полей, упомянутых в предикате, теоретически можно построить такой индекс, который приведет к Seek по этим полям.
...
Рейтинг: 0 / 0
ISNULL() = ISNULL()
    #40073878
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Shakill

SARGable - SEARCH argument able , это свойство именно предиката. не данных и не фактически имеющихся индексов. имеется в виду, что для полей, упомянутых в предикате, теоретически можно построить такой индекс, который приведет к Seek по этим полям.

Во, теперь понятно. Спасибо.
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / ISNULL() = ISNULL()
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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