Может ли блокировка таблицы ускорить оператор обновления в Oracle 10g Enterprise? - PullRequest
2 голосов
/ 30 марта 2011

У нас есть довольно широкая таблица BaseData с 33 миллионами строк.Затем у нас есть запрос на обновление, который соединяет его с несколькими другими таблицами, содержащими все виды параметров, некоторые функции применяются, существует группа по исходному идентификатору, а затем результаты записываются обратно в таблицу BaseData в несколько столбцов.

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

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

Есть ли у вас какие-либо другие советы для больших обновлений?Мы уже разбили его на партии.Каждый пакет находится в отдельном разделе таблицы, а затем несколько обновлений запускаются параллельно.Но все еще слишком медленно.

Ответы [ 3 ]

3 голосов
/ 30 марта 2011

В дополнение к ответу Адама:

Запустите EXPLAIN PLAN для вашего оператора обновления и проверьте план выполнения.

Скорее всего, добавление индексов для поддержки ваших объединений и условий WHERE может ускорить запрос.

3 голосов
/ 30 марта 2011

Короткий ответ: нет, в Oracle использование эксклюзивной блокировки таблицы не помешает другим сеансам ее прочесть или потребует создания согласованного по чтению представления данных.Точно так же в Oracle вы не можете указать сеансу, чтобы он включал «грязное чтение».

Ну, первый вопрос: что медленное - это все работа по объединению и применению функций, или это написаниеназад?Как работает SELECT my_updated_resultset FROM BASEDATA JOIN... по сравнению с вашим оператором обновления?Вы убедились, что существует конфликт между читателями BaseData и процессом обновления?Кроме того, это слишком медленно для бизнеса или просто медленнее, чем вы думаете?

Другой вариант, который следует рассмотреть, - это использовать обмен разделами для выполнения ваших обновлений.Концепция высокого уровня:

  1. CREATE TABLE BASEDATA_XCHG as SELECT * FROM BASEDATA WHERE 1 = 0;
  2. INSERT /*+ append */ INTO BASEDATA_XCHG SELECT my_updated_resultset FROM BASEDATA PARTITION (ONLY_ONE_PARTITION) JOIN...
  3. Создайте все необходимые индексы и ограничения для таблицы BASEDATA_XCHG.
  4. ALTER TABLE BASEDATA EXCHANGE PARTITION (ONLY_ONE_PARTITION) WITH BASEDATA_XCHG

Если вы обновляете большинство строк в разделе таблицы BASEDATA, не обновляйте их - создайте новую таблицу и замените ее.У Тима Гормана есть отличная статья под названием «Масштабирование до бесконечности» , в которой эта концепция рассматривается глубже;Вы можете проверить это.

1 голос
/ 30 марта 2011

Oracle использует сегменты отмены для согласованности чтения (наряду с SCN, читайте подробнее здесь )

Я предполагаю, что эти большие пакетные процессы выполняются в промежуточной области, а не в экземпляре prod, который используется многими различными процессами. Если вы обновляете 25% или более (приблизительные цифры) какой-то большой таблицы, может быть лучше сделать CTAS (создать таблицу как select ...), чем пытаться обновить. Ваш CTAS будет содержать логику обновления для новой таблицы. После этого добавьте indexes / grants / etc в новую таблицу и переименуйте новую в старую. Вы также можете добавить параллельную подсказку и nologging на CTAS, чтобы потенциально ускорить процесс еще больше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...