Индекс Oracle не используется при соединении с другой таблицей - PullRequest
1 голос
/ 08 июля 2011

У меня есть следующий sql, запущенный в базе данных Oracle 10g:

select  /*+ ALL_ROWS */
       to_number(cv.old_value) as cv_id,
       to_number(job.old_value) as job_id
  from amendments,
       amnddets cv,
       amnddets job
 where amendments.table_name = 'TIMESHEET_LAYER'
   and amendments.dml_type = 'D'
   and cv.amnd_id = amendments.amnd_id 
   and cv.column_name = 'CV_ID'
   and job.amnd_id = amendments.amnd_id
   and job.column_name = 'JOB_ID';

Созданы следующие индексы:

create index amendments_dmp_type_upper on amendments upper(dmp_type);
create index amendments_table_name_upper on amendments upper(table_name);
create index amendments_pk on amendments (amnd_id);
create index amended_column_name_idx on amnddets (column_name);
create index amnddets_amnd_id_idx on amnddets (amnd_id);

Я также пытался использовать соединения ANSI (см. Ниже sql), но при этом индексы также не используются, размещение upper() вокруг table_name и dml_type также не оказывает влияния.

Приведенный выше запрос занимает около 30 - 40 секунд, чтобы получить около 2500 строк.

Я посмотрел на план объяснения и не вижу, чтобы использовались индексы amendments для table_name и dml_type.

Explain plain for oracle joins attached

Ниже приведен план объяснения ANSI для:

select  /*+ ALL_ROWS */
       to_number(cv.old_value) as cv_id,
       to_number(job.old_value) as job_id
  from amendments
  JOIN amnddets cv on cv.amnd_id = amendments.amnd_id and cv.column_name = 'CV_ID'
  JOIN amnddets job on job.amnd_id = amendments.amnd_id and job.column_name = 'JOB_ID'
 where upper(amendments.table_name) = 'TIMESHEET_LAYER'
   and amendments.dml_type = 'D';

Explain plan for the ANSI joins

Может ли кто-нибудь посоветовать, почему индексы table_name, dml_type и column_name не используются в приведенном выше запросе?

Ответы [ 2 ]

2 голосов
/ 08 июля 2011

Если вы действительно запустили это, как вы говорите:

create index amendments_dmp_type_upper on amendments upper(dmp_type);

то, что вы фактически создали, это индекс для amendments(dmp_type) без функции upper!

Правильный синтаксис:

create index amendments_dmp_type_upper on amendments (upper(dmp_type));

Возможно, что удивительно, ваше утверждение работает, но слово "upper" трактуется как псевдоним таблицы - это тоже работает:

create index amendments_dmp_type_upper on amendments foo(dmp_type);
1 голос
/ 08 июля 2011

Я не эксперт по Oracle, но, похоже, он не использует (или не может использовать) объединение индексовЭто означает, что вам нужны составные индексы.

create index amnddets_column_name_amnd_id_idx on amnddets (column_name, amnd_id);

create index amendments_dml_type_table_name_amnd_id_idx on amendments (dml_type, table_name, amnd_id)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...