2013-04-12 11 views
3

У меня есть запрос, который выполняет фантастику при выполнении из SQL.INSERT во временную таблицу GTT очень медленно от PL/SQL

Это соединение между таблицей и запросом. Обе таблицы имеют около 4 млн записей. В таблице doc есть индексы растровых изображений, которые я пытаюсь дать. План Explain показывает, что они хорошо помогают, когда я вижу жабу.

Я добавил (а) 2 других подсказки, чтобы увидеть, если они помогут, как видно. Один из них - для прямого доступа APPEND и других, чтобы использовать существующий индекс BTree для pda.

Когда этот запрос выполняется для замещенных переменных из SQL, результаты выполняются мгновенно, но один и тот же запрос внутри процедуры занимает 8 секунд или более.

Помимо плана процедуры, который DBA еще не дал, какие бывают какие-либо вопиющие промахи, которые, возможно, вы думаете? Заранее спасибо.


    INSERT               /*+ APPEND */ 
      INTO tmp_search_gross_docs (document_id, 
             last_name, 
             first_name, 
             person_doc_association_id, 
             association_date) 
     SELECT     /*+INDEX(pda IDX_DOC_PDOC_DOCID) USE_NL(pda doc) */ 
      pda.document_id, 
       last_name, 
       first_name, 
       person_doc_association_id, 
       association_date 
     FROM pda, 
       (SELECT /*+INDEX_COMBINE(attr IDX_BMP_SEARCH_FN,IDX_BMP_SEARCH_LN)*/ 
         document_id, last_name, first_name 
       FROM doc attr 
       WHERE first_name LIKE l_first_name OR last_name LIKE l_last_name) doc 
     WHERE pda.document_id = doc.document_id; 
         ) doc 
       WHERE pda.document_id = doc.document_id; 

EXPLAIN план (от жабы для переменных связывания)

ВСТАВИТЬ ЗАЯВЛЕНИЕ ALL_ROWSCost: 1086010 Б: 15309420 CARDINALITY: 364510
11 НАГРУЗОЧНЫХ AS SELECT TMP_SEARCH_GROSS_DOCS
10 ТАБЛИЦЫ ДОСТУПА индексного ROWID ТАБЛИЦЫ PDA Стоимости: 3 байт: 20 CARDINALITY: 1
9 Стоимость вложенных циклы: 1086010 Б: 15309420 CARDINALITY: 364510
7 Таблицы ДОСТУП ROWID индексной Таблицы атр Стоимость: 23893 Б 8019220 кардинальность: 364510 6 BITMAP ПРЕОБРАЗОВАНИЯ НА ROWIDs
5 растровой или
2 BITMAP MERGE
1 растровый ИНДЕКС ДИАПАЗОН СКАН INDEX (Bitmap) IDX_BMP_SEARCH_FN 4 BITMAP MERGE
3 BITMAP ИНДЕКС ДИАПАЗОН СКАН ИНДЕКС (Bitmap) IDX_BMP_SEARCH_LN 8 INDEX RANGE SCAN ИНДЕКС IDX_PDA_EXP_DOC Стоимость: 2 Количество элементов: 1

мощность 364510 кажется выключен, как таблица содержит 3738562 строк и в течение замещенных значений столбцов в том, где отсчет только 8892.

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

Фактический план PL/SQL по-прежнему недоступен.

Не уверен, что это добавляет ценную информацию или нет. Но мысль все-таки отредактирует. Спасибо

+0

Что еще вы делаете в этой процедуре? –

+0

Не уверен, что это поможет, но в конечном итоге он создает набор записей, который затем считывается приложением. Я должен указать, что я попробовал BULK COLLECT с коллекцией на том же SQL, и это было тоже самое. Как-то чувствуется, что SELECT не принимает оптимальный путь, который он выполняет при выполнении из редактора. – user2275460

ответ

1

Пара вещей, которые вы можете изучить.

  1. Не относится к таблице GTT. Как вы сказали, создайте таблицу в nologging больше, и при вставке используйте подсказку insert append для выполнения прямой загрузки пути.

  2. Кроме того, может возникнуть неправильное представление о скорости запроса, если вы видите результаты от жабы. Программные средства, такие как жаба, автоматически добавляют подсказки для получения первых строк 50/100/200, поэтому запрос может работать быстрее.Вы пытались перейти к последней записи (значок «>» в ​​сетке) и посмотреть, сколько времени потребуется, чтобы получить последнюю строку?

  3. Невозможно настроить запрос или даже написать хороший код, не имея возможности увидеть план. Если это более сложная процедура, вы можете посмотреть такие вещи, как DBMS_PROFILER. ЕСЛИ вы уверены, что это заявление, вызывающее проблему, вы можете начать с SQL-трассировки или плана объяснения.

+0

На # 2 да, запрос возвращает 600 нечетных строк для соответствующих параметров, что я сравниваю производительность. Я пришел к последней записи в результатах да. На 3. да, я убедился, что это утверждение вызывает задержку. План из автономного SQL выглядит хорошо, так как я настроился и перешел к процедуре. Никаких прав на запуск трассировки не существует или фактический план выполнения процедуры пока недоступен. Спасибо за повторение пунктов. – user2275460

2

Во-первых, я не думаю, что вставка в GTT с добавлением имеет любую логику. я могу ошибаться, но из того, что я знаю, добавляет обход буферного кеша и записывает непосредственно в файл, он пишет над отметкой высокой воды и не разрешает запрос до фиксации. GTT не находится в обычных файлах данных - он находится в файлах temp, и он усекается при фиксации (настройки по умолчанию).

Я думаю, что если вам не нужно манипулировать данными после запроса, верните курсор ref в приложение. это в основном одно и то же: много слоев DAL реализовано таким образом.

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

+1

+1 Вы правы, чтобы скептически относиться к использованию GTT с добавлением. Преимущество GTT заключается в том, что он всегда должен быть кэширован; обход кеша для первой записи, вероятно, не поможет. Но он все равно может работать, если GTT специфичен для сеанса, а не для конкретной транзакции. –

0

Adaptive cursor sharing does not apply to LIKE predicates.

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

Одним из возможных решений является заставить Oracle всегда тщательно анализировать ваш запрос. Я использовал это решение, как объяснено Дион Cho в this OTN thread:

dbms_stats.set_table_stats('schema','DOC',num_rows=>null,no_invalidate=>false); 

Hard-синтаксический будет использовать дополнительные ресурсы процессора, но мы надеемся на лучший план будет более чем компенсировать разницу. Это решение вызовет другие несвязанные запросы, требующие жесткого анализа. Вы можете посмотреть на некоторые другие решения, упомянутые в упомянутой теме.

Кроме того, может быть указан ваш INDEX_COMBINE. Между индексами не должно быть запятой. Однако синтаксис подсказок плохо документирован, и парсер подсказок часто будет работать «частично». Ваш намек, вероятно, оценивается как эквивалент /*+INDEX_COMBINE(attr)*/, который может работать или не работать так, как вы этого хотите. Без планов вы никогда не узнаете.

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

+0

Я подтвердил, что в подсказках используются индексы, поэтому синтаксис определенно хорош. Я все еще пытаюсь изучить ваш другой комментарий о настройке жесткого анализа. Как отключить это, если вообще? Учитывая, что в этом сообщении упоминается опасность «конкуренции с библиотечным кешем». – user2275460

+0

Вам, вероятно, не нужно беспокоиться о кеше библиотеки. Если запрос занимает 8 секунд, то он, вероятно, не работает очень часто. Выполнить 'select count (*) из gv $ sql;' и сравнить это с количеством различных запросов, которые ваша процедура создавала бы, если бы она всегда жестко анализировала. Кроме того, я все еще скептически отношусь к тому, что подсказки работают. Я думаю, что это тот случай, когда план объяснения, который вы видите, не * совпадает с реальным планом выполнения. Я не уверен, почему у вас проблемы с получением фактического плана, его должно быть легко достать. –

 Смежные вопросы

  • Нет связанных вопросов^_^