#sql #performance #oracle #sqlplus #toad
#sql #Производительность #Oracle #sqlplus #toad
Вопрос:
Я запускаю запрос, подобный этому:
INSERT INTO TableA (colA, colB)
Select ColA, ColB
from TableB
Это огромная вставка, поскольку она запрашивает более 2 миллионов строк, а затем вставляет их в таблицу. Мой вопрос касается производительности. Когда я запускаю запрос в toad, выполнение запроса занимает около 4-5 минут.
Когда я запускаю запрос через sqlplus, это занимает намного больше времени. Он уже работает более 40 минут и не завершен. Я даже произвел небольшую настройку, отключив вывод сервера на случай, если это повлияет на производительность.
Есть ли какие-либо настройки, о которых я должен знать в отношении выполнения запроса через sqlplus? Есть ли какой-либо способ выяснить разницу в том, как запрос выполняется / обрабатывается разными клиентами?
Примечание: Это единственный способ перенести мои данные из таблицы A в таблицу B. Я просмотрел imp / exp и impdp / expdp, и в моей ситуации это невозможно.
Toad — v . 9.6.1.1 SqlPlus — 9.2.0.1.0 Oracle DB — 10g
Комментарии:
1. нет ли dba.stackoverflow.com ? на самом деле это не связано с программированием, вероятно, это инструментальная вещь? В частности, вам может потребоваться посмотреть, какие параметры устанавливает toad для создаваемых им подключений. sqlplus, вероятно, ничего для вас не делает, в то время как toad, вероятно, делает. Хотя я не знаю, почему это имело бы какое-либо значение для запроса, который ничего не делает на самом клиенте…
Ответ №1:
Похоже, здесь замешано что-то еще. Я бы предположил, что ваш сеанс SQL * Plus блокируется. Можете ли вы проверить v $ lock, чтобы убедиться, что это так? Существует множество скриптов / инструментов, которые можно проверить, чтобы увидеть, на что в данный момент тратится время вашего сеанса. Выясните это, а затем действуйте оттуда. Лично мне нравится скрипт Snapper от Tanel Poder (http://tech.e2sn.com/oracle-scripts-and-tools/session-snapper ).
Ответ №2:
Это может быть тысяча причин. (@John Gardner: Это одна из причин, почему я не большой поклонник dba.stackexchange.com — вы не узнаете, является ли это проблемой программирования или администратора базы данных, пока не узнаете ответ. Я думаю, будет лучше, если мы все будем работать вместе на одном сайте.)
Вот несколько идей:
- Могут быть включены, принудительно или отключены различные настройки сеанса — параллельный dml и параллельный запрос. Посмотрите на свои сценарии входа или информацию о сеансе с помощью
select pdml_stats, pq_status, v$session.* from v$session;
- Блокировка, как предложил @Craig. Хотя я думаю, что на это проще смотреть
select v$session.blocking_session, v$session.* from v$session;
для выявления блокировок. - Задержка очистки блока замедлит выполнение второго запроса. Запуск с
set autotrace on
.db block gets
Иredo size
, вероятно, во второй раз больше (вторая инструкция требует некоторой дополнительной работы, хотя этого, вероятно, недостаточно, чтобы объяснить разницу во времени). - Буферный кэш может ускорить выполнение второго запроса. Запуск с
set autotrace on
, может быть большая разница вphysical reads
. Хотя при таком количестве данных вероятность того, что огромная их часть будет кэширована, вероятно, невелика. - Другие сеансы могут занимать много ресурсов. Посмотрите на
select * from v$sessmetric order by physical_reads desc,logical_reads desc, cpu desc;
Или, может быть, посмотрите на v $ sysmetric_history. - Возможно, вы захотите рассмотреть параллельные и добавить подсказки. Вероятно, вы можете ускорить выполнение этого запроса в 10 раз (хотя у этого подхода есть некоторые недостатки, такие как то, что данные изначально невозможно восстановить).
- Кроме того, для тестирования вы можете захотеть использовать меньшие размеры. Запустите insert с чем-то вроде
and rownum <= 10000
. Настройка производительности очень сложна, это очень помогает, если вы можете часто запускать инструкции. Всегда есть какие-то ошибки, и вы хотите игнорировать выбросы, но вы не можете сделать это только с двумя образцами. - Вы можете посмотреть некоторые подробные статистические данные для каждого запуска, но вам может потребоваться выполнить запрос с
INSERT /* GATHER_PLAN_STATISTICS */...
. Затем запустите это, чтобы найти sql_id:select * from v$sql where sql_text like '%INSERT%GATHER_PLAN_STATISTICS%';
Затем запустите это, чтобы просмотреть детали каждого шага:select * from v$sql_plan_statistics_all where sql_id = '<sql_id from above>';
(В 11g вы можете использовать v $ sql_monitor или, что еще лучше, dbms_sqltune.report_sql_monitor.)
Ответ №3:
Действительно очевидный момент, но, как известно, он сбивает людей с толку … есть ли какие-либо индексы tableA
; если да, то какой-либо из них уникален; и если да, то фиксировали ли вы сеанс Toad перед повторным запуском в SQL * Plus или откатывали его? Как предлагает @Craig, не делать этого — простой способ получить блок. В этом сценарии он никогда не завершится — вы ждете более 40 минут, пока он блокируется при вставке первой строки.
Если есть какие-либо индексы, вам, вероятно, будет лучше удалить их во время выполнения insert и воссоздать их впоследствии, поскольку это обычно значительно быстрее.
Ответ №4:
Как уже предлагали другие пользователи, существует множество факторов, которые могут привести к тому, что оператор, который выбирает / вставляет такое количество данных, будет работать плохо (и непоследовательно). Хотя я видел, как Toad иногда что-то делает для повышения производительности, я никогда не видел, чтобы он делал что-то настолько быстрее, поэтому я склонен думать, что это больше связано с базой данных, а не с инструментом.
Я бы попросил администратора базы данных проверить ваш сеанс и базу данных во время выполнения инструкции slow. Они должны быть в состоянии дать вам некоторое представление о том, что происходит — они смогут проверить наличие любых проблем, таких как блокировка или чрезмерное переключение файлов журнала. Они также смогут отслеживать оба сеанса (Toad и SQL Plus), чтобы увидеть, как Oracle выполняет эти инструкции, и есть ли какие-либо различия и т.д.
В зависимости от того, что вы делаете, они могут даже помочь вам запустить insert быстрее. Например, может быть быстрее отключить индекс, выполнить вставку, а затем перестроить его; или может оказаться возможным временно отключить ведение журнала. Это, очевидно, будет зависеть от вашего точного сценария.
Комментарии:
1. Извините, только что заметил, что это был старый вопрос. Я все равно оставлю ответ здесь — я все еще думаю, что суть этого («поговорите с администратором базы данных») является полезным предложением для всех, кто сталкивается с этим