Оптимизатор хранимых процедур DB2 не использует самый эффективный индекс - PullRequest
2 голосов
/ 23 апреля 2020

У меня есть хранимая процедура, которая возвращает данные на основе параметров p_qds_startTime и p_qds_endTime, которые обычно устанавливаются на период отчетности 365 дней, однако период отчетности может быть установлен всего на 1 день. Таблица, которую запрашивает процедура, содержит много миллионов строк и содержит столбец, содержащий данные xml.

Оптимизатор выбирает использование индекса для sys_start, который может быть очень неэффективным в течение 365-дневного отчетного периода. Для больших отчетных периодов, например, оптимизатор должен использовать индекс xml, относящийся к статусу политики, поскольку только 300 000 записей имеют статус политики «Приложение».

Индекс состояния политики настроен правильно и если я выполняю базовый запрос, подставляя входные параметры для временных меток, план объяснения показывает, что оптимизатор использует этот индекс, если отчетный период превышает 10 дней. Если отчетный период составляет менее 10 дней, он использует индекс sys_start, который также необходим.

Мой вопрос: есть ли способ убедиться, что оптимизатор проверяет входные значения и переоценивает план, который он будет использовать каждый время бежит? Это пакетное задание один раз в день, поэтому не стоит тратить время на это.

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

Вот базовый запрос в SP

select 
      policy_number
      ,year_1_commission_amount
from(
select 
      xml_policy.policy_number,
      t002.SYS_START,
      xml_policy.policy_status,
      xml_policy.year_1_commission_amount,
      ROW_NUMBER() over (partition by xml_policy.POLICY_NUMBER order by t002.SYS_START DESC) RN
from 
      DB.t002
      ,xmltable
      (
      '$i/*:AddProtQuoteResponse/*:plan[1]/*:policy[*:policyStatus = "Application"]' passing t002.QDS_XML AS "i"
      columns
      policy_number varchar(30) path '*:policyNumber',
      policy_status varchar(12) path '*:policyStatus',
      year_1_commission_amount decimal(11,2) path ''
      ) as xml_policy
where 
      sys_start > CAST(p_qds_startTime AS TIMESTAMP(12)) 
      and sys_start <= CAST(p_qds_endTime AS TIMESTAMP(12)) 
      and t002.QDS_XML_TYPE_ID = 3 
)
where rn = 1;

1 Ответ

3 голосов
/ 23 апреля 2020

Попытайтесь повторно связать рутинный пакет с параметром REOPT ALWAYS:

CALL SYSPROC.REBIND_ROUTINE_PACKAGE ('SP', 'SP_SCHEMA.SP_SPECIFICNAME', 'REOPT ALWAYS');

, где 2-й параметр является результатом:

SELECT RTRIM(ROUTINESCHEMA)||'.'||SPECIFICNAME
--, PARM_COUNT
FROM SYSCAT.ROUTINES R
WHERE ROUTINESCHEMA='SP_SCHEMA' AND ROUTINENAME='SP_NAME';

SP_SCHEMA & SP_NAME - схема и название вашей процедуры. У вас может быть несколько строк в выводе запроса выше (если у вас есть несколько подпрограмм с одинаковой парой), и вам нужно выбрать правильную строку с соответствующим указанным c именем.

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