Как проверить, для какого столбца создать индекс для оптимизации производительности

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

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

    Select * from ORDER_MART FOL where FOL.PARENT_PROD_SRCID 
IN 
(
select e.PARENT_PROD_SRCID
from SRC_GRP a 
JOIN MAR_GRP b ON a.h_lpgrp_id = b.h_lpgrp_id    
JOIN DATA_GRP e ON e.parent_prod_srcid = b.H_LOCPR_ID
WHERE a.CHILD_LOCPR_ID != 0 
AND dt_id BETWEEN 20170101 AND 20170731 
AND valid_order = 1  
AND a.PROD_TP_CODE like 'C%'    
)
AND FOL.PROD_SRCID = 0 and IS_CAPS = 1;

Ниже приведен мой план выполнения запроса: введите здесь описание изображения


person Andrew    schedule 22.08.2017    source источник
comment
Какие таблицы разбиты по каким ключам? Каков план объяснения? Почему нельзя добавить индексы?   -  person Mat    schedule 22.08.2017
comment
Я добавил план выполнения запроса и не могу добавить индексы из-за ограничений разрешений в PROD   -  person Andrew    schedule 22.08.2017
comment
У вас есть exists, но нет оговорки о корреляции. Это выглядит подозрительно.   -  person Gordon Linoff    schedule 22.08.2017
comment
на самом деле раньше я использовал IN вместо этого, просто чтобы попробовать, улучшит ли это производительность. Я не понимаю пункт о корреляции?   -  person Andrew    schedule 22.08.2017
comment
@GordonLinoff, как мне использовать пункт о корреляции в существующих   -  person Andrew    schedule 22.08.2017
comment
Просто добавленное примечание: без какого-либо индекса, как бы вы ни старались, вы не сможете добиться наилучшей производительности, верно?   -  person Renato Afonso    schedule 23.08.2017
comment
@RenatoAfonso да, я знаю, но я просто пытаюсь сократить время, необходимое для выполнения запроса.   -  person Andrew    schedule 23.08.2017


Ответы (1)


Select * 
from ORDER_MART FOL 
     INNER JOIN (
           select distinct e.PARENT_PROD_SRCID
           from SRC_GRP a 
           JOIN MAR_GRP b ON a.h_lpgrp_id = b.h_lpgrp_id    
           JOIN DATA_GRP e ON e.parent_prod_srcid = b.H_LOCPR_ID
           WHERE a.CHILD_LOCPR_ID != 0 -- remove the lines from                               INT_CDW_DV.S_LOCAL_PROD_GRP_MAIN  with child prod srcid equal to 0
           AND dt_id BETWEEN 20170101 AND 20170731 
           AND valid_order = 1 --and is_caps=1 
           AND a.PROD_TP_CODE like 'C%'    
          ) sub ON sub.PARENT_PROD_SRCID=FOL.PARENT_PROD_SRCID 
where FOL.PROD_SRCID = 0 and IS_CAPS = 1;

Что, если вы используете JOIN вместо IN и добавляете отдельные, чтобы уменьшить количество строк в подзапросе.

person StanislavL    schedule 22.08.2017
comment
да немного быстрее. Мой запрос выполняется за 523,968 секунды, а ваш запрос выполняется за 438,493 секунды. Но все же это занимает немного. Не можем ли мы оптимизировать его больше? - person Andrew; 22.08.2017
comment
К сожалению, у меня нет магии, чтобы оптимизировать его вслепую :-). Опубликуйте таблицы БД (столбцы/типы). Можно ли применить больше ограничений к подзапросу. Например. FOL.PROD_SRCID = 0 and IS_CAPS = 1 можно ли также применить его к подзапросу, чтобы уменьшить количество строк? - person StanislavL; 22.08.2017
comment
К сожалению, нет дополнительных условий, которые я могу указать в подзапросе. И нет специального столбца, такого как CLOB, используемого в таблицах запросов. Так что это обычный varchar, числовой тип данных. - person Andrew; 22.08.2017