Оптимизация SQL-запросов Oracle - получение подсчетов на основе поля varchar - PullRequest
0 голосов
/ 19 февраля 2019

Оптимизация запроса

У меня есть запрос на получение данных из одной таблицы и получение двух отсчетов из двух других таблиц на основе поля типа VARCHAR TYPE.Мне нужно получить счетчик из TABLE2, где TYPE = TABLE1.TYPE и счетчик из TABLE3, где TYPE = TABLE1.TYPE

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

 SELECT     a.ID, 
    a.FIELD1, 
    a.FIELD2, 
    a.TYPE, 
    GET_COUNT_1(a.TYPE) as COUNT1,
    GET_COUNT_2(a.TYPE) as COUNT2,
FROM TABLE1 a

Мой исходный запрос был:

SELECT  a.ID, 
    a.FIELD1, 
    a.FIELD2, 
    a.TYPE, 
    (SELECT COUNT(*) FROM TABLE2 b WHERE b.TYPE=a.TYPE) as COUNT1,
    (SELECT COUNT(*) FROM TABLE3 c WHERE c.TYPE=a.TYPE) as COUNT2
FROM TABLE1 a

Ответы [ 2 ]

0 голосов
/ 19 февраля 2019

Если у вас нет индекса для table2(TYPE), использовать подзапрос смертельно, так как вы будете многократно (для каждой строки TABLE1) выполнять FULL TABLE SCAN .

Судя по всему, кэширование подзапроса Oracle, которое могло бы вас спасти, не сработало.

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

Но есть простое решение для предварительного вычисления количества в подзапросе и присоединения результата к TABLE1.

Обратите внимание, что вычисляет только countодин раз для каждого типа и , а не для каждой строки таблицы TABLE1

with cnt as 
(select type, count(*) cnt
from table2 group by type),
cnt2 as 
    (select type, count(*) cnt
    from table3 group by type)
select a.ID, 
    a.FIELD1, 
    a.FIELD2, 
    a.TYPE,
    b.cnt cnt1
    c.cnt cnt2
from  TABLE1 a 
left outer join cnt b
on a.type = b.type
left outer join cnt2 c
on a.type = c.type

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

0 голосов
/ 19 февраля 2019

Для вашего запроса вам нужен индекс для table2(type).

Два подзапроса абсолютно одинаковы, за исключением псевдонима таблицы.Если у вас действительно есть две разные таблицы или если вы используете разные столбцы, вам понадобится соответствующий индекс для этого выражения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...