Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Почему не используется индекс запросе..? [IB6.x]


Страницы:   1 2

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), то его просто игнорировать.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо