2014-02-11 2 views
1

Мне нужно было создать временную таблицу, а затем использовать эту временную таблицу в запросе выбора. Когда я помещаю эти утверждения в функцию, потребуется много времени для выполнения второго оператора. Как это:SELECT после CREATE TABLE AS занимает много времени для запуска

BEGIN 
    CREATE TABLE temp AS SELECT…. 
    INSERT INTO target_table SELECT * FROM tableA join temp… 
END; 

Я понял, что когда я запускаю их в индивидуальном порядке около 60 секунд между прогонами второго утверждением занимает около 2 секунд для запуска. Если бы я ждал 45 секунд, это займет много времени. Например, если я выполнить следующие инструкции по одному (не в функции):

CREATE TABLE temp AS SELECT…. 

SELECT pg_sleep(60); 

INSERT INTO target_table SELECT * FROM tableA join temp… 

Это займет некоторое время, чтобы выполнить INSERT один. Но когда я выделил их и объединил их, навсегда потребовалось выполнение.

Я попытался поместить их в функцию в разных блоках BEGIN/END. Нравится

BEGIN 
    CREATE TABLE temp AS SELECT…. 
    SELECT pg_sleep(120); 
END; 

BEGIN 
    INSERT INTO target_table SELECT * FROM tableA join temp… 
END; 

Все еще не работает.

Почему ожидание между ними? Почему они не работали при вводе функции? Есть ли обходной путь для этой проблемы?

ответ

0

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

  1. Использовать подзапрос вместо временной таблицы. Оптимизатор очень хорош при обработке сложного SQL.
  2. Использование общего выражения таблицы (предложение WITH): если результирующий набор очень велик, данные будут материализованы во временный сегмент, а если нет, то его можно рассматривать как подзапрос.
  3. Используйте глобальную временную таблицу. Вам не придется использовать немедленный запуск и индексировать таблицу или собирать статистические данные по ней (редко требуется, из-за динамической выборки оптимизатора).

Чтобы диагностировать вашу реальную проблему, я бы посмотрел на мониторинг сеанса с помощью трассировки или с использованием AWR.

+0

Я использовал подзапрос. По какой-то причине подзапрос также занимал очень много времени. Это было намного быстрее с временным столом. Я также использовал CREATE TABLE temp DROP ON COMMIT, и это тоже не сработало. – toanong

+0

Хорошо, что синтаксис полностью недействителен. msgstr "создать глобальную временную таблицу (col1, col2 ...) при фиксации строк удаления". Я думаю, вам было бы лучше попробовать и диагностировать причину медленного подзапроса, возможно, переписывая его как общее табличное выражение, прежде чем переходить на временные таблицы. –

2

Я сильно подозреваю, что проблема связана с выбором плана из-за того, что таблица еще не имеет статистики. Попыться:

CREATE TABLE temp AS SELECT…. 
ANALYZE; 
INSERT INTO target_table SELECT * FROM tableA join temp… 

P.s. +1 для использования реальных эллипсов.

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