2014-12-30 5 views
3

я написал ниже запрос, который имеет много «и» операторов, я хотел бы знать, как оптимизировать производительность ниже запроса [я могу удалить некоторые из «и» Операторов]ORACLE QUERY - ОПТИМИЗАЦИЯ

SELECT I.date, 
       K.somcolumn, 
       L.somcolumn, 
       D.somcolumn 
     FROM Table1 I, 
       Table2 K, 
       Table3 L, 
       Table4 D 
     WHERE I._ID = K._ID 
       AND K.ID = L._ID 
       AND L._ID = I._ID 
       AND I._CODE = L._CODE 
       AND K.ID = D._ID(+) 
       AND L._ID IN (SELECT _id 
             FROM I 
             WHERE UPPER (someflag) = 'TRUE' 
            GROUP BY _id 
            HAVING COUNT (*) > 1) 
       AND L._ID IN (SELECT _id 
             FROM I 
             WHERE UPPER (code) = 'OPEN' 
            GROUP BY _id 
            HAVING COUNT (*) > 1) 
    ORDER BY I._ID, I._CODE; 
+0

Если возвращено несколько строк, вы можете попробовать сделать счет из таблицы I в качестве нового возвращаемого столбца, используя скалярный подзапрос. Вы также можете попробовать использовать предложение WITH, создавая временную таблицу из таблицы I. Только идеи. Я не могу дать ответ, поскольку не могу подтвердить свои идеи. – user2672165

+0

Также он может быть значительно быстрее, используя 'EXISTS', чем' IN', поскольку индекс может использоваться. 'EXISTS (SELECT NULL FROM I WHERE L._id = _id AND UPPER (code) = 'OPEN' GROUP BY _ID HAVING COUNT (*)> 1)'. Поскольку индекс может использоваться для кода _id, а someflag - это, возможно, кандидаты для индекса растрового изображения. – user2672165

ответ

2

вы не можете комбинировать любые из условий, насколько я могу судить, но вы можете улучшить запрос и уменьшить количество AND операторов, используя стандартный синтаксис: JOIN

SELECT I.date, 
    K.somcolumn, 
    L.somcolumn, 
    D.somcolumn 
FROM Table1 I 
INNER JOIN Table2 K ON I._ID = K._ID 
INNER JOIN Table3 L ON K.ID = L._ID 
LEFT JOIN Table4 D ON K.ID = D._ID 
WHERE L._ID IN (SELECT _id 
    FROM I 
    WHERE UPPER (someflag) = 'TRUE' 
    GROUP BY _id 
    HAVING COUNT (*) > 1) 
AND L._ID IN (SELECT _id 
    FROM I 
    WHERE UPPER (code) = 'OPEN' 
    GROUP BY _id 
    HAVING COUNT (*) > 1) 
ORDER BY I._ID, I._CODE; 

при том, что, как основы, вы май получите повышение оптимизации, если вы присоединитесь к условиям подзапроса, а не используете коррелированные подзапросы. Нет гарантий, но что-то вроде этого может помочь:

SELECT I.date, 
    K.somcolumn, 
    L.somcolumn, 
    D.somcolumn 
FROM Table1 I 
INNER JOIN Table2 K ON I._ID = K._ID 
INNER JOIN Table3 L ON K.ID = L._ID 
LEFT JOIN Table4 D ON K.ID = D._ID 
INNER JOIN (
    SELECT _id 
    FROM I 
    WHERE UPPER (someflag) = 'TRUE' 
    GROUP BY _id 
    HAVING COUNT (*) > 1 
) someflagtrue ON L._ID = someflagtrue._id 
INNER JOIN (
    SELECT _id 
    FROM I 
    WHERE UPPER (code) = 'OPEN' 
    GROUP BY _id 
    HAVING COUNT (*) > 1 
) codeopen ON L._ID = codeopen._id 
ORDER BY I._ID, I._CODE; 
0

Вы можете заменить два подзапроса одним.

Старые подзапросы:

SELECT _id 
    FROM I 
    WHERE UPPER (someflag) = 'TRUE' 
GROUP BY _id 
    HAVING COUNT (*) > 1) 

    SELECT _id 
    FROM I 
    WHERE UPPER (code) = 'OPEN' 
GROUP BY _id 
    HAVING COUNT (*) > 1) 

Нового подзапрос:

SELECT _ID 
    FROM I 
GROUP BY _ID 
HAVING COUNT(CASE WHEN UPPER(SOMEFLAG) = 'TRUE' THEN 1 ELSE 0 END) > 0 
    AND COUNT(CASE WHEN UPPER(CODE) = 'OPEN' THEN 1 ELSE 0 END) > 0 

В большинстве случаев это должно быть по крайней мере, немного быстрее, так как это может уменьшить количество полных сканирование таблиц и объединения. Но сложно сказать, будет ли он быстрее в вашей системе, поскольку для оптимизатора существует так много возможных вариантов.

После очистки запроса следующим шагом для настройки производительности является создание плана объяснения. Запустите explain plan for select ...;, а затем запустите select * from table(dbms_xplan.display);. Это покажет вам, как выполняется запрос, что может дать вам подсказку о том, что происходит медленно и что можно улучшить. Добавьте полную версию плана объяснения к вашему вопросу, если вам нужна дополнительная помощь. Это также может помочь добавить информацию о количестве строк в соответствующих таблицах, количестве строк и каковы индексы.