Стратегия улучшения производительности Oracle DELETE

У нас есть установка Oracle 11g, которая начинает становиться большой. Эта база данных является базой для параллельной системы оптимизации, выполняемой на кластере. Ввод в процесс содержится в базе данных вместе с результатами шагов оптимизации. Вход включает в себя данные конфигурации и некоторые двоичные файлы (с использованием 11g SecureFiles). Выход включает в себя данные 1D, 2D, 3D и 4D, которые в настоящее время хранятся в БД.

Структура БД:

/* Metadata tables */
Case(CaseId, DeleteFlag, ...) On Delete Cascade CaseId
OptimizationRun(OptId, CaseId, ...) On Delete Cascade OptId
OptimizationStep(StepId, OptId, ...) On Delete Cascade StepId

/* Data tables */
Files(FileId, CaseId, Blob) /* deletes are near instantateous here */

/* Data per run */
OnedDataX(OptId, ...)
TwoDDataY1(OptId, ...) /* packed representation of a 1D slice */

/* Data not only per run, but per step */
TwoDDataY2(StepId, ...)  /* packed representation of a 1D slice */
ThreeDDataZ(StepId, ...) /* packed representation of a 2D slice */
FourDDataZ(StepId, ...)  /* packed representation of a 3D slice */
/* ... About 10 or so of these tables exist */

Жнец script приходит каждый день и ищет случаи с DeleteFlag = 1 и переходит с DELETE FROM Case WHERE DeleteFlag = 1, позволяя продолжить каскады.

Эта стратегия отлично работает для чтения/записи, но теперь превосходит наши возможности, когда мы хотим очистить данные! Ручка удаляет случай занимает ~ 20-40 минут в зависимости от размера и часто перегружает наше пространство архиватора. Следующая крупная версия продукта будет использовать подход "с нуля" для решения проблемы. Следующий незначительный выпуск должен оставаться в пределах данных, хранящихся в базе данных.

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

  • REF Разделение, но вопрос КАК? Мне бы хотелось сделать INTERVAL на Case и REF для остальных, но это не поддерживается. Есть ли способ вручную переместить OptimizationRun на CaseId через триггер?
  • Отключить журналы архивации/повтора для удаления? Не удалось найти СОВЕТ, чтобы пойти с этим. Не уверен, что это даже возможно.
  • Обрезать? Для этого, вероятно, потребуется какая-то сложная настройка таблицы. Но, возможно, я не рассматриваю все свои варианты. (за каждый ответ, пораженный)

Чтобы помочь проиллюстрировать проблему, данные, о которых идет речь, варьируются от 15MiB до 1.5GiB в любом месте от 20k до 2M строк.

Обновление: Текущий размер БД составляет ~ 1,5 ТБ.

Ответы

Ответ 1

Удаление данных - чертовски работа для базы данных. Он должен создавать перед изображениями, обновлять индексы, записывать журналы повтора и удалять данные. Это медленный процесс. Если у вас есть окно для выполнения этой задачи, проще всего и быстрее создавать новые таблицы, содержащие нужные данные. Удалите старые таблицы и переименуйте новые таблицы. Это требует некоторой работы по настройке, что очевидно, но очень хорошо можно сделать. На один шаг менее решительным является падение индексов перед удалением. Мое голосование будет идти за CTAS (Create Table As Select from) и строить новые таблицы. Хорошая схема секционирования, безусловно, была бы полезна, возможно, в следующем выпуске Oracle может объединить интервальное и ссылочное разбиение. Было бы очень приятно иметь.

Отключение ведения журнала.... не может быть выполнено для удаления, но CTAS может использовать nologging. Сделайте резервную копию, когда будете готовы, и обязательно передайте файлы данных в резервную базу данных, если она у вас есть.

Ответ 2

Только некоторые мысли:

  • Я предполагаю, что у вас есть индексы для всех внешних ключей. ON DELETE CASCADE будет удерживать блокировки на уровне строк до тех пор, пока не удастся удалить Case, и без индексов будут удерживать блокировки таблиц, которые, как я полагаю, будут очень медленными.

  • Есть ли у вас какие-либо отложенные ограничения? Это, скорее всего, замедлит процесс каскадирования Oracle через различные удаленные таблицы.

  • Вы пытались выполнить удаление отдельно для всех затронутых таблиц (вместо того, чтобы полагаться на удаление каскада)? Не так просто, но вы можете быть удивлены.

EDIT:

Еще одна мысль. Вы можете подумать о том, чтобы сделать SOFT delete в таблице Case, что означает, что у вас есть поле статуса, которое сообщит вашему приложению, если этот случай следует рассмотреть. Этот флаг может иметь много разных значений, но, возможно, "A" для активных и "I" для неактивных. Предполагая, что вы всегда используете Case в качестве движущей/основной таблицы в соединениях с другими таблицами, вы можете избежать удалений HARD все вместе (а иногда и выполнять очистку бездействия в любом расписании, если хотите). Разумеется, приложения должны знать об этом флаге, и вы будете привязаны к тому, чтобы присоединиться к таблице Case. Может или может не соответствовать вашей ситуации...

Ответ 3

CASCADE DELETE выполняется медленно медленнее, er, строка за строкой.

Некоторые параметры:

  • Сделайте снимок вашей работы для очистки всех случаев, которые нужно удалить в таблицу царапин с помощью CTAS. Затем проведите свою петлю работы по этой таблице, удалив каждый случай (и его детей) индивидуально. Это может быть неприятно, особенно если вы столкнулись с миллионами строк потомков. Недавно нам пришлось изменить один из процессов [business redacted], который сделал это, чтобы определить, какие конечные родители подсчитали ребенка, что было бы проблематичным, а затем использовать ограничитель rownum при удалении с проблемной дочерней таблицей. Это не быстро, но, по крайней мере, это более безопасно с точки зрения отмены/повтора, поставив верхнюю границу того, насколько велика любая транзакция.

  • Если вы используете CASCADE DELETE в качестве удобства, вы всегда можете этого не делать. Вам нужно будет написать более сложную процедуру очистки, которая удалит из дерева зависимостей "снизу вверх".

  • Если вы можете позволить генерировать отмену/повторное создание на мягком удалении, вы можете изменить разбивку конечного родителя на DeleteFlag, а затем разделить дочерние элементы BY REFERENCE, все таблицы с помощью ENABLE ROW MOVEMENT. Вы понесете затраты на отмену/повторную доставку для перемещения строк при мягком удалении, но когда придет время окончательно очистить, это будет обрезать разделы, где DeleteFlag = 1, не более.

  • Добавление хранилища относительно дешево. Если есть опция хранения на основе даты, используйте ее и просто используйте опцию мягкого удаления, чтобы скрыть данные из внешнего интерфейса приложения. Это неэлегантно, но тогда, значит, CASCADE DELETE.

Ответ 4

Используйте Enterprise Manager для создания отчета AWR и запускайте его через анализатор statspack, который даст вам подробные инструкции об узких местах в вашей системе. Отчет AWR представляет собой текстовый файл, содержащий все виды данных о том, что сделала база данных в течение определенного времени и сколько времени прошло... Этот анализатор statspack является своего рода автоматическим администратором баз данных, который говорит вам, что делать.

Забудьте разделы, пока Statspack Analyzer не сообщит вам, что они могут быть полезными, и у вас есть несколько незанятых дисков, которые вы можете использовать для распространения ввода-вывода.

Не думайте об усечении. Он заставляет совершить...

Кстати, я не связан с анализатором Statspack, но я считаю это очень жизнеспособным общим подходом к настройке для Oracle, особенно если там нет DBA.

Ответ 5

Не рекомендуется для живой базы данных.

  • Я отключил ограничения внешнего ключа, ссылающиеся на таблицу, которая медленно удаляется.
  • Я выполнил удаление
  • Включить внешние ключи снова.