((:prm is null) or (field=:prm)) и индексы

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Ответить
sasha
Сообщения: 4
Зарегистрирован: 23 ноя 2004, 15:48

((:prm is null) or (field=:prm)) и индексы

Сообщение sasha » 26 ноя 2004, 12:57

возможно ли задействовать индекс по полю field
в запросе -

select * from table
where ((:prm is null) or (field=:prm)) and .....

в таком виде естественно работает

select * from table
where (field=:prm) and .....

dimitr
Разработчик Firebird
Сообщения: 888
Зарегистрирован: 26 окт 2004, 16:20

Сообщение dimitr » 26 ноя 2004, 13:44

В настоящее время невозможно.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 26 ноя 2004, 14:12

оптимизатор строит план в момент выполнения prepare. На этот момент значения параметров неизвестны. Допустим, в :prm оказался null. Тогда надо выбрать все записи. Если при этом использовать индекс, то это будет совершенно лишним (выборка всех с использованием индекса - это лишь дополнительные затраты на чтение страниц индекса).
Так что тут использование индекса под вопросом, в смысле как это дело ввести в ядро, причем менять план запроса на этапе execute...

dimitr
Разработчик Firebird
Сообщения: 888
Зарегистрирован: 26 окт 2004, 16:20

Сообщение dimitr » 26 ноя 2004, 14:43

Дим, даже Оракл делает в этом случае фулл-скан :)

Vemer
Сообщения: 8
Зарегистрирован: 09 ноя 2004, 15:01

избавиться от Null

Сообщение Vemer » 27 ноя 2004, 11:20

:idea: Не проще от Null избавиться, заменив его на 0 или ''?

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 27 ноя 2004, 14:29

to dimitr - это я помню :-)
to Vemer - в данном случае null тут абсолюно ни при чем.
ключевой момент именно в
where ((:prm is null) or
замени на
where ((:prm = 0) or

и будет то же самое.

sasha
Сообщения: 4
Зарегистрирован: 23 ноя 2004, 15:48

Сообщение sasha » 29 ноя 2004, 08:48

Vemerу от нула избавится не получится,
т.к. запрос внутри процедуры, а prm один из
ее параметров, если пользователь не указал его,
то и учитывать в запросе его бы нехотелось.
здесь есть 3 варианта:
Первый - тот что уже указал
Второй - по if выполнять различные запросы
Третий - составлять запрос в процедуре и
выполнять - execute statement
у всех свои минусы..
Первый - запрос не оптимизируется.
Второй - при большом количестве параметров процедуры сильно усложняются
Третий - минусы execute statement.

Ответить