Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Оптимизация запросов  [new]
JMPX
Guest
Всем привет,
подскажите пожалуйста как оптимизировать данный кусок кода
select 1 from table
[b]where IsNull(field, 0) = 0[/b]

у меня есть табличка на несколько тысяч записей и поле которое может иметь значение NULL, 0, и все что больше 0.
В таком варианте запрос занимает 6 сек, когда пишу field = 0 or field is null - тоже самое, есть некластерный индекс по этому полю.
Как же оптимизировать это условие?
Заранее благодарен!
24 июл 14, 12:16    [16351050]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запросов  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
select 1 from table where field = 0
union all
select 1 from table where field is null;
24 июл 14, 12:30    [16351168]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запросов  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
iap
select 1 from table where field = 0
union all
select 1 from table where field is null;
Пожалуй, здесь лучше подойдёт
select 1 from table where field = 0
union
select 1 from table where field is null;
24 июл 14, 12:31    [16351180]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запросов  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
iap
iap
select 1 from table where field = 0
union all
select 1 from table where field is null;

Пожалуй, здесь лучше подойдёт
select 1 from table where field = 0
union
select 1 from table where field is null;
Хотя, зависит от контекста.
Если это стоит в EXISTS, то UNION ALL, конечно, предпочтительнее
24 июл 14, 12:32    [16351188]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запросов  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
JMPX,

Если речь про Seek vs Scan, то разница быть должна, когда вы пишете "field = 0 or field is null", оптимизатор может использовать два точечных поиска, один по 0, другой по null, если сочтет это выгодным исходя из селективности данных значений.

Простой пример:
use test;
go
if object_id('t1') is not null drop table t1;
go
create table t1(id int identity primary key, a int, b char(10) default '');
insert t1(a) select number from master..spt_values 
where number <> 0; --comment this
insert t1(a) values(NULL),(0);
create index ix_a on t1(a);
go
set statistics xml on
select * from t1 where a = 0 or a is null -- Seek
select * from t1 where isnull(a,0) = 0 -- Scan
set statistics xml off

В первом случае поиск по индексу ix_a, во втором сканирование кластерного.
Но если вы закомментируете строчку --comment this, то есть в таблице появится много значений 0, селективность упадет и поиск + лукап - станет не таким выгодным как просмотр кластерного индекса, тогда планы будут одинаковые. ВОзможно ваш случай, может быть вам надо сделать покрывающий индекс.
24 июл 14, 12:43    [16351291]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запросов  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
SomewhereSomehow
оптимизатор может использовать два точечных поиска, один по 0, другой по null

Поправка, поиск конечно не точечный, а динамический.
24 июл 14, 12:51    [16351366]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запросов  [new]
JMPX
Guest
iap,

спасибо конечно но так не получиться так как у мене не просто
select 1 from table

a
select field1
,        field2
,        field3
,        ......
,        field214  
from table

и дублировать 2 запроса как то не очень еффективно
24 июл 14, 13:06    [16351453]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запросов  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
JMPX
iap,

спасибо конечно но так не получиться так как у мене не просто
select 1 from table


a
select field1
,        field2
,        field3
,        ......
,        field214  
from table


и дублировать 2 запроса как то не очень еффективно
А для сервера - самое оно!
Преобразование OR в UNION - обычный способ оптимизации.

Однако, вам же не только я ответил...
24 июл 14, 13:10    [16351475]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запросов  [new]
Алексей Куренков
Member [заблокирован]

Откуда: Москва
Сообщений: 567
JMPX,

select 1 from table
where field = 0 or field is null


здесь оптимизатор сам найдет план. можно и без юнионов - скорее всего в плане запросов объединение и увидите
24 июл 14, 15:24    [16352479]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запросов  [new]
JMPX
Guest
Алексей Куренков,

но я же писал
JMPX
когда пишу field = 0 or field is null - тоже самое
24 июл 14, 15:26    [16352493]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запросов  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8807
JMPX
Алексей Куренков,

но я же писал
JMPX
когда пишу field = 0 or field is null - тоже самое


Значит индекс не работает. Смотрите план запроса. Вы в первом варианте слукавили и написали
автор
select 1

вместо
автор
select field1
, field2
, field3
, ......
, field214
from table


Поиск по индексу просто по полю field не будет использован в этом случае, в лучшем случает будет просмотр.
24 июл 14, 15:43    [16352636]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запросов  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
Алексей Куренков
здесь оптимизатор сам найдет план. можно и без юнионов - скорее всего в плане запросов объединение и увидите
Ну не всегда ведь. Написали же, зависит от селективности. Вариант с UNION ALL надежнее, хотя и выглядит громоздко.
24 июл 14, 20:00    [16354151]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запросов  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8807
Я потестировал так и сяк - UNION показывает несколько лучшие результаты при количестве записей свыше 100к вместо OR, меньше 1к лучше использовать просто скан таблицы без индексов. Кластеризованный индекс еще немного улучшает скорость по сравнению с кучей.
24 июл 14, 21:50    [16354568]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запросов  [new]
SIMPLicity_
Member

Откуда: (((@)))
Сообщений: 8877
Я тоже - за кластеризованный индекс и isnull(field,0) ибо селективность по полю с двумя значениями, ИМБО, бессмысленна и оптимизатор "кладёт" на ваш индекс по field, - один скан меняется на два сика (это в лучшем! случае, а в худшем - опять будет два скана).
Если запрос гораздо сложнее - лучше приведите полностью запрос (наверняка, как указал
iap
Хотя, зависит от контекста.
Если это стоит в EXISTS, то UNION ALL, конечно, предпочтительнее
). Короче, "курите" план. Может быть имеет смысл посмотреть (в случае долгого громоздкого плана) на некластерный индекс с включёнными полями? Вообще, select по таблице из 100 тыс. записей за 6 секунд, ИМБО, явно указывает на scan большой (в смысле "широкой") таблицы, если конечно большая часть времени НЕ тратится на пересылку полученных данных от скуля в студию.
25 июл 14, 00:50    [16355217]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить