SQL Plus против Toad IDE - выполнение вставки в SQL Plus занимает значительно больше времени - PullRequest
1 голос
/ 20 мая 2011

Я выполняю запрос, подобный этому:

INSERT INTO TableA (colA, colB)
Select ColA, ColB 
from TableB

Это огромная вставка, так как она запрашивает более 2 миллионов строк и затем вставляет их в таблицу. У меня вопрос по производительности. Когда я запускаю запрос в жабе, его выполнение занимает около 4-5 минут.

Когда я запускаю запрос через sqlplus, он занимает больше времени. Это уже работает 40 минут +, и это не закончено. Я даже сделал небольшую настройку, отключив выходной сервер в случае, если это повлияло на производительность.

Есть ли какие-либо настройки, о которых мне следует знать в связи с выполнением запроса через sqlplus? Есть ли способ узнать разницу в том, как запрос выполняется / обрабатывается разными клиентами?

Примечание. Это единственный способ перенести мои данные из таблицы A в таблицу B. Я изучил imp / exp и impdp / expdp, и в моей ситуации это невозможно.

Жаба - v. 9.6.1.1 SqlPlus - 9.2.0.1.0 БД Oracle - 10 г

Ответы [ 4 ]

5 голосов
/ 20 мая 2011

Звучит так, будто в этом есть что-то еще. Я предпочитаю предположить, что ваш сеанс SQL * Plus блокируется. Можете ли вы проверить v $ lock, чтобы увидеть, так ли это? Есть много скриптов / инструментов, чтобы проверить, на что тратится ваше время в данный момент. Пойми это, а потом иди оттуда. Мне лично нравится сценарий Снаппера Танела Подера (http://tech.e2sn.com/oracle-scripts-and-tools/session-snapper).

2 голосов
/ 21 мая 2011

Это может быть тысяча вещей. (@Джон Гарднер: Это одна из причин, почему я не большой поклонник dba.stackexchange.com - вы не будете знать, является ли это проблемой программирования или проблемой DBA, пока не узнаете ответ. Я думаю, что лучше, если мы все работают вместе на одном сайте.)

Вот несколько идей:

  • Различные настройки сеанса - параллельный 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 раз быстрее (хотя у этого подхода есть некоторые недостатки, такие как данные изначально невозможно восстановить).
  • Также для тестирования вы можете использовать меньшие размеры. Запустите вставку с чем-то вроде 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.)
0 голосов
/ 03 января 2016

Как уже говорили другие люди, есть много вещей, которые могут привести к тому, что оператор, который выбирает / вставляет такое количество данных, работает плохо (и непоследовательно). Хотя я видел, как Toad иногда делал что-то для повышения производительности, я никогда не видел, чтобы он делал что-то , поэтому намного быстрее, поэтому я склонен думать, что это больше связано с базой данных, чем с инструментом.

Я бы попросил администраторов БД проверить ваш сеанс и базу данных, пока выполняется медленный оператор. Они должны быть в состоянии дать вам некоторое представление о том, что происходит - они смогут проверить наличие проблем, таких как блокировка или чрезмерное переключение файлов журнала. Они также смогут отслеживать оба сеанса (Toad и SQL Plus), чтобы увидеть, как Oracle выполняет эти операторы, и есть ли какие-либо различия и т. Д.

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

0 голосов
/ 22 мая 2011

Действительно очевидный момент, но известно, что он сбивал людей с толку ... есть ли индексы на tableA;если так, то любой из них уникален;и если да, то вы зафиксировали или откатили сеанс Toad, прежде чем снова запустить его в SQL * Plus?Как говорит @Craig, это не простой способ получить блок.В этом сценарии он никогда не закончится - ваше 40-минутное ожидание пока оно блокируется при вставке первой строки.

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

...