Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Оптимизация запроса с условием PATINDEX  [new]
defragmentator
Member

Откуда:
Сообщений: 20504
Добрый день!

Пишу запрос вида:
SELECT * FROM A, B
WHERE A.ID=B.ID and (PATINDEX('%@%', A.[email])>0)

Очень долго отрабатывает.
Насколько я понимаю, причина в том, что оптимизатор не включает условие (PATINDEX('%@%', A.[email])>0)
в предварительный отбор записей в таблице A, и поэтому условие проверяется по произведению всех записей.
1) Почему он так делает?
2) В каких случаях (для каких выражений вместо PATINDEX) оптимизатор будет предварительно фильтровать таблицу A ?
3) Как соптимизировать данный запрос ?
2 сен 13, 16:03    [14785035]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса с условием PATINDEX  [new]
Crimean
Member

Откуда:
Сообщений: 13147
LIKE конечно
2 сен 13, 16:06    [14785059]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса с условием PATINDEX  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Crimean
LIKE конечно
A.[email] LIKE '%@%'
не шибко лучше на самом деле.
2 сен 13, 16:11    [14785097]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса с условием PATINDEX  [new]
iap
Member

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

хорошо бы выкинуть звёздочку, запятую и WHERE.
Применить подходящий JOIN ... ON
2 сен 13, 16:12    [14785110]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса с условием PATINDEX  [new]
Crimean
Member

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

а больше вариантов без "сильного колдунства" тут и не будет :)
2 сен 13, 16:13    [14785121]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса с условием PATINDEX  [new]
defragmentator
Member

Откуда:
Сообщений: 20504
В общем случае, для произвольной функции, хотелось бы знать, как можно "колдонуть".
2 сен 13, 16:28    [14785252]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса с условием PATINDEX  [new]
Гость333
Member

Откуда:
Сообщений: 3683
defragmentator
Насколько я понимаю, причина в том, что оптимизатор не включает условие (PATINDEX('%@%', A.[email])>0)
в предварительный отбор записей в таблице A, и поэтому условие проверяется по произведению всех записей.

Как вы это поняли? Из плана запроса?
2 сен 13, 16:30    [14785272]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса с условием PATINDEX  [new]
defragmentator
Member

Откуда:
Сообщений: 20504
Гость333,

по времени выполнения
2 сен 13, 16:36    [14785323]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса с условием PATINDEX  [new]
hpv
Member

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

можно попробовать "прибить гвоздем". Сделать Filtered Index )
2 сен 13, 16:39    [14785350]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса с условием PATINDEX  [new]
Гость333
Member

Откуда:
Сообщений: 3683
defragmentator
Гость333,

по времени выполнения

А давайте лучше посмотрим по плану запроса, там всё будет видно, и предварительный отбор, и прочее.
2 сен 13, 16:40    [14785362]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса с условием PATINDEX  [new]
defragmentator
Member

Откуда:
Сообщений: 20504
Гость333,

Вот простенький пример:
declare @a table(id int, name varchar(8));
declare @b table(id int, name varchar(8), email varchar(18));

insert @a values(1, '1a')
insert @a values(2, '2a')
insert @b values(1, '1b', '1b@mail.ru')
insert @b values(2, '2b', '2b@mail.ru')
select * from @a a, @b b where PATINDEX('%@%', b.[email])>0
Там в плане видно, что таблица @b предварительно фильтруется (ставится предикат).
Так что всё ок.
Оригинальный запрос немного не такой, посложнее, но суть та же
2 сен 13, 16:44    [14785393]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса с условием PATINDEX  [new]
defragmentator
Member

Откуда:
Сообщений: 20504
В причине разобрался частично. Почему-то оптимизатор требует не тот индекс
2 сен 13, 17:07    [14785564]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса с условием PATINDEX  [new]
Гость333
Member

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

Ну, если всё ещё нужна помощь, то как минимум предоставьте структуру таблиц и индексов, и запрос в оригинальном (а не упрощённом) виде.
2 сен 13, 17:26    [14785717]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса с условием PATINDEX  [new]
Алексей Куренков
Member [заблокирован]

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

добавьте поле вычисляемое и индекс по нему - спасет вашу беду однозначно ))))

alter table A add pidx as patindex('%@%',[email]);
create index ix1 on A (pidx, ID) include (оставшиеся поля которые выводите);
2 сен 13, 19:34    [14786423]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация запроса с условием PATINDEX  [new]
Crimean
Member

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

все верно, только если у вас с базой ископаемыми либами работа идет - будьте готовы воевать с конекшен стрингами
ничего страшного, просто бояться не нужно. а то все эти "вкусности" работают только при определенных сетах
2 сен 13, 19:36    [14786427]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить