Как удалить столбец из огромной базы данных Oracle?

Есть таблица в Oracle огромного размера ~200ГБ и удаление столбца в ней через ALTER TABLE table DROP COLUMN column займет более 15 часов. Какие есть способы это ускорить или хотя бы, если ускорить невозможно, как это делать правильно? Неужели только DROP COLUMN?

Версия Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production

Читал про SET UNUSED, но вроде как это тоже самое? Вернее, это не очистит таблицу физически и нужно всё равно использовать DROP UNUSED COLUMNS. Также нашёл что-то про SHRINK SPACE, но чото не понял как она устроена и как пользоваться. Это должно быть сочетание вместе с SET UNUSED? Хотя как минимум стало ясно, что это невозможно выполнить параллельно. Единственное, чего можно добиться - это не блокировать таблицу во время удаления

P.S. Мой вопрос больше касается актуальности данных. Я прочитал множество форумов и обнаружил, что все ответы и вопросы очень старые. Я хотел бы получить быстрый, точный и исчерпывающий ответ о том, как лучше всего выполнить удаление


Ответы (1 шт):

Автор решения: Superproger77

Сслыка на принятый ответ этого вопроса с SO

Какой-никакой перевод

"Удаление столбца из большой таблицы редко имеет смысл. Он должен воссоздать 100% блоков данных, создавая массовый повтор и чтение отдельных блоков, и это делается последовательно, без использования преимуществ параллельной обработки.

Вместо этого просто установите столбец неиспользуемым (alter table mytable set unused (mycol)) и забудьте об этом. По сути, он исчезает и почти исчез, за ​​исключением того, что он все еще использует пространство (оно все еще существует в блоках данных). Но кого это волнует? В большинстве случаев это нормально.

Если вам нужна экономия места сразу, после того, как столбец станет неиспользуемым, просто физически реорганизуйте таблицу с помощью ALTER TABLE MOVE, что можно выполнить с помощью параллелизма:

alter table mytable move parallel (degree 16) update indexes

Это позволит удалить неиспользуемый столбец из блоков данных без необходимости выполнять гимнастику для воссоздания таблицы. На этом этапе столбец удаляется как логически, так и физически, но по какой-то причине Oracle сохраняет память о нем в user_tab_cols. Честно говоря, не представляю, с какой целью.

Единственным недостатком наличия неиспользуемого столбца является то, что у вас есть скрытый столбец (видимый в user_tab_cols но не в user_tab_columns это может вызвать проблемы с обменом разделами, которые требуют, чтобы отдельная таблица, которую вы заменяете разделом, имела точно такую ​​же структуру в словаре - она ​​должна иметь один и тот же скрытый/неиспользуемый столбец в одном и том же физическом положении, что может будет немного сложно воссоздать. К счастью, Oracle предоставила create table... for exchange with table... синтаксис для автоматического воспроизведения точной необходимой структуры, включая эти надоедливые неиспользуемые столбцы. Так что это не проблема. Я бы просто оставил его неиспользованным и положил бы конец.

Если вам в конечном итоге понадобится полностью удалить его оттуда, вам нужно будет выполнить фактическое удаление столбца (что после реорганизации/перемещения может быть быстрее, минуя повтор, хотя оно все равно будет сканировать всю таблицу) или воссоздать таблицу. Если до этого дойдет, в какое-то удобное время позже, возможно, совпадающее с другим обслуживанием (сжатием, архивированием и т. д.), используйте метод CTAS/замены таблицы, уже рекомендованный другими, чтобы полностью удалить столбец из блоков. Вы также можете использовать пакет PL/SQL dbms_redefinition, который сделает это за вас, хотя я никогда не видел необходимости в его использовании, поэтому не знаю, как он работает и какие у него есть ограничения.

Но какой бы метод вы ни использовали, суть в том, что это не обязательно делать сейчас или, возможно, когда-либо."

→ Ссылка