![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Почему не используется индекс запросе..? [IB6.x]
pashtet © (2004-04-12 11:14:00)Вот такой запрос идет по NATURAL, а не по PRIMARY KEY.
select * from mytable
where (:id is null or id=:id)
как с этим бороться?
СУБД - Yaffil 884
Johnmen (2004-04-12 15:45:00) [1]В частности это неверно, о чем ты сам сказал в [16]
:)
pashtet (2004-04-12 15:43:00) [2]вот что сказали на sql.ru :
Вообще-то в случае когда в WHERE сравнивается входной параметр с чем-то, не являющимся полем таблицы ... индексы в FB не используются
Johnmen (2004-04-12 14:30:00) [3]>pashtet ©
С таким where бороться за использование индексов, по-моему бессмысленно...
pashtet (2004-04-12 14:07:00) [4]
> Johnmen ©
where
(o.IS_DELETED=0) and
(:TERMINAL is null or o.ID_TERMINAL = :TERMINAL) and
(:ID is null or o.ID_ORDER =:ID) and
(:F is null or o.D_PROJECT >=:F) and
(:T is null or o.D_PROJECT <:T+1) and
(:ORDERTYPE is null or o.ID_ORDERTYPE = :ORDERTYPE) and
(:PTYPE is null or (o.ID_PTYPE = :PTYPE and :ORDERTYPE is not null)) and
(:PROD is null or o.ID_PROD = :PROD) and
(:AGENT is null or o.ID_AGENT IN (SELECT ID_AGENT from AGENTS WHERE ID_PARENT=(SELECT ID_PARENT from AGENTS WHERE ID_AGENT=:AGENT))) and
(:MANAGER is null or o.ID_MANAGER = :MANAGER) and
(:CB_CONFIRM is null or (:CB_CONFIRM = 1 and o.D_CONFIRM is not null) or (:CB_CONFIRM = 0 and o.D_CONFIRM is null)) and
(:CB_REJECT is null or (:CB_REJECT = 1 and o.D_REJECT is not null) or (:CB_REJECT = 0 and o.D_REJECT is null)) and
(:CB_SHIPPED is null or (:CB_SHIPPED = 1 and (exists (select * from PACKPOS p where o.ID_ORDER = p.ID_ORDER))) or (:CB_SHIPPED = 0 and (not (exists (select * from PACKPOS p where o.ID_ORDER = p.ID_ORDER))))) and
(:CB_ZERO is null or (:CB_ZERO=1 and (o.PRICE+o.PRICEA)=0) or (:CB_ZERO=0 and (o.PRICE+o.PRICEA)<>0)) and
(:CURRENCY is null or ID_CURRENCY = :CURRENCY)
sniknik (2004-04-12 14:01:00) [5]лутше уж процедура будет больше чем время выборки.
Johnmen (2004-04-12 14:01:00) [6]Туману нагнал ещё больше...
Приведи целиком твоё условие WHERE.
pashtet (2004-04-12 13:55:00) [7]
> IF ((:P1 IS NULL) OR (:P2 IS NULL) ...) THEN
> <первый запрос и т.д.>
> ELSE
> <второй запрос и т.д.>
ну так ведь придется для 8 параметров написать 8! условий, соответственно повторить 8! тело выборки.
Johnmen (2004-04-12 13:39:00) [8]>pashtet © (12.04.04 13:33) [19]
IF ((:P1 IS NULL) OR (:P2 IS NULL) ...) THEN
<первый запрос и т.д.>
ELSE
<второй запрос и т.д.>
Или я чего не понял ?
pashtet (2004-04-12 13:33:00) [9]
> Johnmen © (12.04.04 13:01) [18]
а как в условии WHERE поставить if?
или предлагаете на саспенд поставить иф?
Johnmen (2004-04-12 13:01:00) [10]>pashtet © (12.04.04 12:42) [17]
>а если входных пареметров - 8 штук
А в одном ифе разве нельзя проанализировать ?
pashtet (2004-04-12 12:42:00) [11]
> Romkin © (12.04.04 12:38) [15]
> БЕй на два селекта, а какой запускать - смотри в if :)
а если входных пареметров - 8 штук
то писать 8! if-ов ???
pashtet (2004-04-12 12:38:00) [12]
> Johnmen © (12.04.04 12:28) [14]
> Это из-за наличия жесткого условия :IDORDER is null
не знаю жесткого или нет, но если оставить "жесткое" условие и вместо or написать and то индекс использоваться БУДЕТ.
помоему дело в том что оптимизатор лажает на таких запросах.
кто может предложить другой способ организации таких процедур-выборок??
Romkin (2004-04-12 12:38:00) [13]Это из-за наличия or :))
БЕй на два селекта, а какой запускать - смотри в if :)
Johnmen (2004-04-12 12:28:00) [14]>pashtet © (12.04.04 12:12) [13]
Это из-за наличия жесткого условия :IDORDER is null
pashtet (2004-04-12 12:12:00) [15]
> Johnmen ©
индекс - PRIMARY KEY
не используется
т.к. IBExpert дает след. план:
PLAN (ORDERS NATURAL)
Johnmen (2004-04-12 12:09:00) [16]С чего ты взял, что не используется ?
И есть ли он вообще ? И какой ?
Nikolay M. (2004-04-12 12:07:00) [17]
> for select NAME from ORDERS
> where (:IDORDER is null or ID_ORDER = :IDORDER)
1) В ИБ есть возможность указать оптимизатору запросов испотльзовать какой-либо индекс?
2) А если побить на два запроса и сцепить UNION-ом?
pashtet (2004-04-12 12:06:00) [18]Разве никто не делал такие выборки??
кто может подсказать как сделать подобные выборки , что бы использовался индекс?
pashtet (2004-04-12 11:42:00) [19]поясню от куда возник вопрос.
есть ХП которая делает выборку
create procedure ORDERS_GET(
IDORDER integer)
returns(
NAME varchar(20))
as
begin
for select NAME from ORDERS
where (:IDORDER is null or ID_ORDER = :IDORDER)
into :NAME
do suspend;
end
такая процедура хороша тем, что если нам надо выбрать все заказы или только один, то мы запускаем процедуру с параметром null либо со значением.
и когда запускаем процедуру с известным параметром то в запросе не используется индекс!!!!
asp (2004-04-12 11:41:00) [20]Кщд (12.04.04 11:23) [3]>
Иногда может быть удобным программирование по схеме: если параметр такой-то содержит конкретное значение, то возвращать выборку по данному значению, в случае если параметр не определен (is null), то его просто игнорировать.