powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Как ускорить выборку по условию "OR"?
25 сообщений из 27, страница 1 из 2
Как ускорить выборку по условию "OR"?
    #39264880
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Приветствую!

Далее представленный запрос выполняется непозволительно долго, ищу возможность ускорить.
В запросе два условия соединенные через "OR"

Если оставить любое из этих условий, запрос летает.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
   SELECT 
      t.*, 
      rowid 
   FROM 
      transponder t
   WHERE 
      t.FK_Objekt = :FK_OBJEKT or    -- условие "1"
      t.FK_Auftrag in                -- условие "2"
      (
         SELECT a.ID
         FROM auftrag a 
         WHERE 
            a.ID = :FK_AUFTRAG or
            a.FK_Objekt = :FK_OBJEKT
      )



Буду благодарен за советы, заранее спасибо.
...
Рейтинг: 0 / 0
Как ускорить выборку по условию "OR"?
    #39264886
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
P.S.
Oracle 9.2, если это важно
...
Рейтинг: 0 / 0
Как ускорить выборку по условию "OR"?
    #39264907
Кроик Семён,

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
   SELECT 
      t.*, 
      rowid 
   FROM 
      transponder t
   WHERE 
      t.FK_Objekt = :FK_OBJEKT    -- условие "1"
union all
   SELECT 
      t.*, 
      rowid 
   FROM 
      transponder t
   WHERE 
      t.FK_Auftrag in                -- условие "2"
      (
         SELECT a.ID
         FROM auftrag a 
         WHERE 
            a.ID = :FK_AUFTRAG or
            a.FK_Objekt = :FK_OBJEKT
      )
...
Рейтинг: 0 / 0
Как ускорить выборку по условию "OR"?
    #39264923
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
спасибо, идея понятна
но мне нужен редактируемый запрос. Написал такое:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
   SELECT 
      t.*, 
      rowid 
   FROM 
      transponder t
   WHERE 
      t.ID in
      (
         -- условие "1"
         SELECT 
            t1.ID
         FROM
            transponder t1
         WHERE 
            t.FK_Objekt = :FK_OBJEKT
         
         UNION ALL
            
         -- условие "2"
         SELECT 
            t2.ID
         FROM
            transponder t2
         WHERE
            t2.FK_Auftrag in 
            (
               select a.ID
               from auftrag a 
               where 
                  a.ID = :FK_AUFTRAG or
                  a.FK_Objekt = :FK_OBJEKT
            )
      )  



стало еще хуже (раз в 5)
...
Рейтинг: 0 / 0
Как ускорить выборку по условию "OR"?
    #39264925
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
P.S.
а вообще, есть ли возможность создать индекс , который бы работал на условии "OR"?
...
Рейтинг: 0 / 0
Как ускорить выборку по условию "OR"?
    #39264927
ora601
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кроик СемёнПриветствую!

Далее представленный запрос выполняется непозволительно долго, ищу возможность ускорить.
В запросе два условия соединенные через "OR"

Если оставить любое из этих условий, запрос летает.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
   SELECT 
      t.*, 
      rowid 
   FROM 
      transponder t
   WHERE 
      t.FK_Objekt = :FK_OBJEKT or    -- условие "1"
      t.FK_Auftrag in                -- условие "2"
      (
         SELECT a.ID
         FROM auftrag a 
         WHERE 
            a.ID = :FK_AUFTRAG or
            a.FK_Objekt = :FK_OBJEKT
      )



Буду благодарен за советы, заранее спасибо.
План покажи для медленного и быстрого?
...
Рейтинг: 0 / 0
Как ускорить выборку по условию "OR"?
    #39264939
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
оригинальный запрос
...
Рейтинг: 0 / 0
Как ускорить выборку по условию "OR"?
    #39264940
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
быстрый 1
...
Рейтинг: 0 / 0
Как ускорить выборку по условию "OR"?
    #39264941
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
быстрый 2
...
Рейтинг: 0 / 0
Как ускорить выборку по условию "OR"?
    #39264946
pihel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кроик Семёна вообще, есть ли возможность создать индекс , который бы работал на условии "OR"?
Кроик Семёнбыстрый 2
вот or на котором работают индексы
...
Рейтинг: 0 / 0
Как ускорить выборку по условию "OR"?
    #39264952
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pihelКроик Семёнбыстрый 2
вот or на котором работают индексы

вобщем то да....

проверил, индексы перестают работать из-за подзапроса "IN"
...
Рейтинг: 0 / 0
Как ускорить выборку по условию "OR"?
    #39264971
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Какие индексы существуют у таблицы transponder ?

Как минимум нужна ДВА индекса, на поля FK_Objekt - наблюдается
и на поле FK_Auftrag - не наблюдается

Статистика собрана?

AFAIK:
1)
Вообще-то Oracle оптимизатор сам IN может превратить в Union (The USE_CONCAT hint instructs the optimizer to transform combined OR-conditions in the WHERE clause of a query into a compound query using the UNION ALL set operator).

2) Все эти Intex to bitmap - от лукавого. Я бы лично тому, кто их придумал, руки бы из задницы оторвал. Они чисто для недоделанных кривых говнокодных OLAP (т.к. в нормальном OLAP и индекс был бы bitmap и Btree to bitmap делать бы не понадобилось). Но когда они в OLTP системах начинают вылезать - тушите свет. IMHO & AFAIK

Конечно статистика данных у автора не известно, но на мой взгляд Nested Loop + Concat, Nested Loop + Concat и нефиг извращаться. IMHO
...
Рейтинг: 0 / 0
Как ускорить выборку по условию "OR"?
    #39264974
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
переписал запрос, отделив дру от друга части с разными bind - переменными, разнеся их в стороны, и запрос резко (раза в 3-4) ускорился.

но самое непонятное: план запроса остался как у оригинального "медленного"

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
   -- было
   SELECT 
      t.*, 
      rowid 
   FROM 
      transponder t
   WHERE 
      t.FK_Objekt = :FK_OBJEKT or 
      t.FK_Auftrag in                
      (
         SELECT a.ID
         FROM auftrag a 
         WHERE 
            a.ID = :FK_AUFTRAG or
            a.FK_Objekt = :FK_OBJEKT
      )




Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
   -- стало
   SELECT 
      t.*, 
      rowid 
   FROM 
      transponder t
   WHERE 
      -- условие "1"
      t.FK_Objekt=:FK_OBJEKT or
      exists (
         SELECT 1 
         FROM auftrag a 
         where 
            a.ID=t.FK_Auftrag and 
            a.FK_Objekt=:FK_OBJEKT
      ) or
   

      -- условие "2"
      t.FK_Auftrag=:FK_AUFTRAG
   ORDER BY
      t.transpondernr
...
Рейтинг: 0 / 0
Как ускорить выборку по условию "OR"?
    #39264984
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А правильно понимаю, что в целом это эквивалентно следующему запросу?
(запросы не эквивалентны по SQL, но подозреваю по бизнесу одно и то же).
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
SELECT /*+ USE_CONCAT */
   t.*, 
   rowid 
FROM 
   transponder t
   WHERE 
      t.FK_Objekt = :FK_OBJEKT or 
      t.FK_Auftrag = :FK_AUFTRAG or
      t.FK_Auftrag in
      (
         SELECT a.ID
         FROM auftrag a 
         WHERE 
            a.FK_Objekt = :FK_OBJEKT
      )
...
Рейтинг: 0 / 0
Как ускорить выборку по условию "OR"?
    #39264992
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev,

в точку (даже порядок условий тот же, я очень удивлен)
это был мой самый первый запрос, который я сел ускорять
...
Рейтинг: 0 / 0
Как ускорить выборку по условию "OR"?
    #39264996
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Покажи его план (с хинтом) и какие индексы существуют на табличке
...
Рейтинг: 0 / 0
Как ускорить выборку по условию "OR"?
    #39265125
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev,

спасибо за участие. Сейчас не могу ответить, завтра как доберусь до компа все выложу.
...
Рейтинг: 0 / 0
Как ускорить выборку по условию "OR"?
    #39265146
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plsql
1.
UNION ALL

может выдать данные, отличные от основного запроса
...
Рейтинг: 0 / 0
Как ускорить выборку по условию "OR"?
    #39265327
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
скрипт для создания таблицы transponder

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
CREATE TABLE Transponder (
       ID                   INTEGER NOT NULL,
       FK_Farbe             INTEGER NOT NULL,
       FK_Objekt            INTEGER NULL,
       FK_Auftrag           INTEGER NULL,
       TransponderNr        VARCHAR2(20) NOT NULL,
       CodeNr               VARCHAR2(20) NULL,
       IsGesperrt           NUMBER(1) NULL,
       Bemerkungen          CLOB NULL,
       CONSTRAINT XPKTransponder 
              PRIMARY KEY (ID)
);

CREATE INDEX XIF1Transponder ON Transponder (FK_Farbe  ASC);
CREATE INDEX XIF2Transponder ON Transponder (FK_Objekt  ASC);
CREATE INDEX XIF3Transponder ON Transponder (FK_Auftrag  ASC);

ALTER TABLE Transponder
       ADD  ( CONSTRAINT Transponder_FK_Auftrag
              FOREIGN KEY (FK_Auftrag)
                             REFERENCES Auftrag
                             ON DELETE SET NULL ) ;

ALTER TABLE Transponder
       ADD  ( CONSTRAINT Transponder_FK_Objekt
              FOREIGN KEY (FK_Objekt)
                             REFERENCES Objekt
                             ON DELETE SET NULL ) ;

ALTER TABLE Transponder
       ADD  ( CONSTRAINT Transponder_FK_Farbe
              FOREIGN KEY (FK_Farbe)
                             REFERENCES TransponderFarbe
                             ON DELETE SET NULL ) ;




...
Рейтинг: 0 / 0
Как ускорить выборку по условию "OR"?
    #39265337
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
P.S.
сорри, запостилось раньше времени, продолжаю
...
Рейтинг: 0 / 0
Как ускорить выборку по условию "OR"?
    #39265368
nata44845
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кроик Семён, А советник в OEM ничего по этому поводу не советует? (Если Oracle Enterprise конечно)

В SQL Monitor зайди найди свой запрос и там вызови советника.
Он там сам иногда планы интересные составляет.
...
Рейтинг: 0 / 0
Как ускорить выборку по условию "OR"?
    #39265421
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1) Индексы на поля есть, IMHO хинтовать до посинения, пока Oracle не станет делать CONCAT + использовать индексы.

Ну и параллельно разбираться, почему он сейчас вместо индексов и CONCAT уходить в Full Table Scan.

2) В общем, правильное решение сказал Элементарно Ватсон:

Запрос должен разложиться на 3-и простейших части + union all. Это можно сделать или руками или хинтами.

3) Ну и последний вариант, поиск по индексу ДЕЙСТВИТЕЛЬНО дороже (медленнее), чем full table scan. Oracle прав. Бороться бессмысленно )))

IMHO
...
Рейтинг: 0 / 0
Как ускорить выборку по условию "OR"?
    #39265443
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevБороться бессмысленно )))

спасибо

остановился тогда на этом варианте 19351570 , который по непонятным причинам в 4 раза быстрее
...
Рейтинг: 0 / 0
Как ускорить выборку по условию "OR"?
    #39265459
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsevхинтовать до посиненияВместо хинтования до посинения иногда полезно включать мозг.
Трансформации запросов в Оракле тоже имеют свои границы и он не может развернуть в concat когда в одном из OR фигурирует in.
Так же concatenation работает проблемно когда больше двух альтернатив в OR - не забываем что при увеличении числа альтернатив - число веток в плане растет как степень двойки.
Для желающих смотреть что проиходит - прямая дорога в раздел transformation in 10053.

Если просто цель добиться исключительно индексного доступа, то очевидных варианта два
- развернуть в union all вручную
- добиться соединения индексов, но это извращение.

2ТС: Заглядывай иногда в раздел final query в 10053, чтоб видеть итоговый запрос.
В 90% "переписывания" не имеют никакого смысла когда человек оптимизирует методом тыка без желания понять.
...
Рейтинг: 0 / 0
Как ускорить выборку по условию "OR"?
    #39265479
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dbms_photoshopТрансформации запросов в Оракле тоже имеют свои границы и он не может развернуть в concat когда в одном из OR фигурирует in.

Спасибо. Не знал
...
Рейтинг: 0 / 0
25 сообщений из 27, страница 1 из 2
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Как ускорить выборку по условию "OR"?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]