Oracle перенести таблицу в другую схему
Я использую PL \ SQL Developer от AllroundAutomations. Моя задача - импортировать схему с именем EN в другую схему (сейчас ее не существует) с именем E9.
Мне удалось сделать дамп схемы с помощью Tools --> Export User Objects , так что теперь у меня есть файл EN.sql
Итак, вот мои вопросы?
- Как сделать файл EN.dump?
- Чтобы импортировать его в другую схему, мне нужно сначала создать новую схему (E9) от пользователя sysdba?
- А есть ли возможность импортировать схему из интерфейса PL \ SQL Developer? По какой-то причине я не могу подключиться к sqlplus, что еще больше усугубляет ситуацию.
1 ответ
В PL / SQL Developer есть инструменты Экспорт таблиц и Импорт таблиц , с помощью которых можно импортировать / экспортировать файлы dmp с помощью утилит EXP и IMP. См. Справку разработчика PL / SQL:
Экспорт таблиц:
Инструмент «Экспорт таблиц» позволяет вам экспортировать одно или несколько определений таблиц и их данные в файл, чтобы вы могли импортировать таблицы позже. После запуска инструмента экспорта таблиц вы можете выбрать пользователя и таблицы, которые вы хотите экспортировать, выберите метод экспорта ( Oracle Export , SQL Inserts или PL / SQL Developer) и установите различные параметры, которые применяются к методу экспорта .
Импорт таблиц :
Инструмент «Импорт таблиц» позволяет импортировать определения таблиц и данные из файла, который ранее был экспортирован с помощью инструмента «Экспорт таблиц», описанного в предыдущей главе. Как и в случае с инструментом «Экспорт таблицы», существует 3 метода импорта таблиц, каждый со своим собственным форматом файла .
P.S. Как вы видите, схема, в которую вы хотите импортировать, уже должна существовать.
Но таким образом можно экспортировать / импортировать только таблицы. Поэтому, если вы хотите экспортировать всю схему, используйте утилиту через командную строку, см. Пример:
Команда для экспорта схемы:
exp userid=dba/dbapassword OWNER=username DIRECT=Y FILE=filename.dmp
Это создаст файл дампа экспорта.
Чтобы импортировать файл дампа в другую пользовательскую схему, сначала создайте нового пользователя в SQLPLUS:
SQL> create user newuser identified by 'password' quota unlimited users;
Затем импортируйте данные:
imp userid=dba/dbapassword FILE=filename.dmp FROMUSER=username TOUSER=newusername
У меня есть четыре таблицы в схеме с именем DEMO. Я хочу переместить / клонировать / скопировать их в другую схему с именем TEST.
Можно ли переместить таблицу, сменив владельца с DEMO на TEST?
Я использую Oracle 11 и Oracle sql developer 4.
Их нельзя переместить, но можно скопировать / клонировать. Может ли ТЕСТ увидеть ДЕМО-таблицы? Или вы подключены к БД как пользователь с привилегиями DBA? Есть ли какие-либо индексы или ссылочные ограничения?
@AlexPoole У меня есть все привилегии, я пробовал обновить SYS.ALL_ALL_TABLES set OWNER = 'TEST', где TABLE_NAME = 'DEMO_TABLE', но я получаю ORA-01031: недостаточные привилегии даже в XE
Нет, никогда не обновляйте данные в SYS таблицах. Или любой другой встроенный аккаунт. Вы действительно не хотите испортить словарь данных.
Это хороший путь, но SQL Developer позволяет копировать таблицы (щелкните правой кнопкой мыши таблицу в проводнике), если у вас есть необходимые права, или вы можете сделать то же самое с помощью SQL. Но то, как вы это делаете, немного зависит от сложности - в частности, от зависимостей между таблицами. Экспорт / импорт дампа сделает все это за вас.
Вы можете использовать утилиты перекачки данных Oracle, чтобы экспортировать таблицы, а затем импортировать их в другую схему,
Установка Oracle :
Экспорт :
Импорт :
используйте remap_schema (и, если нужно, remap_tablespace ):
Если в таблицах есть внешние ключи, которые вы переназначаете, эта точка на другие таблицы в DEMO схеме, которые вы не переназначили, тогда переназначение попытается переназначить и их, и не удастся создать внешние ключи (поскольку таблица не существует в TEST схеме) но все равно следует импортировать данные. Просмотрите выходные данные, IMPDP чтобы найти эти сбои, а затем используйте, например:
Создать соответствующие внешние ключи.
Спасибо за ответ, мне удалось решить проблему с помощью sql-разработчика. Нажав - инструменты - скопируйте базу данных и выбрав нужные таблицы. Таким образом можно копировать любой объект между схемами. Я думаю, что в фоновом режиме он делает то же самое, что и экспорт / импорт вашего ответа.
@MasterYi Просто убедитесь, что SQL Developer также скопировал первичные / внешние ключи, ограничения, индексы и т. Д., Иначе он мог бы просто копировать структуру и данные таблицы.
В чем разница между параметрами TABLES и INCLUDE в impdp. Вышеуказанные шаги могут быть выполнены с помощью INCLUDE Param (импорт отдельной таблицы из полной резервной копии expdp).
Если у вас есть доступ к старой схеме из новой, вы можете использовать:
CREATE table_name UNRECOVERABLE AS SELECT * FROM sourceSchema.SOURCE_table;
Это воссоздает таблицу по новой схеме; а затем вы можете удалить таблицу из старой схемы, если хотите.
Нет, вам придется делать это отдельно. Достаточно легко сгенерировать DDL, чтобы воссоздать их, если они вам нужны - например, SELECT DBMS_METADATA.get_ddl ('INDEX', index_name) FROM user_indexes WHERE TABLE_NAME = 'OLD_TABLE_NAME';
Несколько вещей, которые происходят во время завершения работы, могут вызвать замедление: данные записаны от кэша до диска, профиль пользователя разгружен, сервисы останавливаются, и (дополнительно) файл подкачки может быть очищен.
Из них я не думаю, что очищаемый файл подкачки вызвал бы "синие" экраны, и я определенно не думаю, что данные, записанные от кэша до диска, могли замедлить вещи кроме экстремальных или маловероятных ситуаций.
Иногда плохо записанный сервис будет отказываться останавливаться правильно, и в случае профиля пользователя, не разгружающегося правильно, что-то где-нибудь поддерживает, соединяет его, возможно программное обеспечение AV или некоторое другое внешнее программное обеспечение.
Предложенные советы по устранению неисправностей, в дополнение к вышеупомянутому, сразу включали бы закрытие после начальной загрузки (т.е. не входя в систему), чтобы видеть, немного ли процесс быстрее, выходя из системы вместо того, чтобы закрыться, чтобы видеть, существуют ли задержки там и выборочно отключение сервисов (но быть осторожными здесь), чтобы видеть, виновато ли что-либо нестандартное.
Я был бы потрясен, если бы было более быстрое решение, чем CREATE TABLE ВЫБОР AS. Экспорт и импорт, используете ли Вы классическую версию или версию DataPump, собираются потребовать, чтобы Oracle считала всю таблицу из диска и пишет всю таблицу в диск в новой схеме, точно так же, как CTAS, но с временным шагом записи данных в файл дампа и чтение его из файла дампа. Вы могли стать творческими и попытаться передать ouput по каналу утилиты экспорта к утилите импорта и иметь обоих экспорт и импорт, работающий одновременно, чтобы потенциально постараться не писать все данные в диск, но затем Вы просто работаете для устранения части ввода-вывода, которые делают экспорт и импортируют по сути медленнее. Плюс, обычно легче параллелизировать CTAS, чем попытаться параллелизировать и экспорт и импорт.
Преимущество выполнения экспорта и импорта, с другой стороны, то, что можно переместить ограничения, индексы, и другой зависимый возражает автоматически. Если Вы делаете CTAS, необходимо будет создать индексы и ограничения отдельно после того, как данные заполняются.
Экспортируйте схему на oldschema, но установите rows=n так, чтобы никакие данные не были экспортированы. Используйте DDL для составления новой таблицы. Затем используйте select into неоднократно для перемещения блоков данных, когда это не повлияет на производительность слишком много. Когда все данные перемещены, используют DDL для создания индексов.
Принятие Вас использует 10 г или выше, я использовал бы Объект преобразования данных, поскольку это - эффективность. Вот хороший, краткий обзор утилит. Там не просто, переименовывают операцию, чтобы сделать то, что Вы хотите сделать - Вы оказываетесь перед необходимостью перемещать данные. Я действительно сталкивался с этим интересным методом.
Вот ответ на вопрос: Как переместить таблицу в другую схему? автор создает таблицу с разделением по диапазонам, а затем создает макет для новой таблицы. Затем он : заменить таблицу t1_temp фиктивным разделом обмена на таблицу t1, включая индексы без проверки; изменить фиктивную таблицу раздела обмена t1_temp на таблицу kutrovsky.t1, включая индексы без проверки;
Первая команда «присваивает» сегмент данных таблице t1_temp. Вторая команда «назначает» сегмент данных таблице t1 у нового владельца
. Это не так просто, как в SQL Server, куда вы могли бы переместить людей. Обращайтесь к Humanresources: ALTER SCHEMA HumanResources TRANSFER Person.Address;
A client asked me, “How can I move a table to another schema in Oracle?” The quick answer I gave him is, “not possible”. You have to rebuild it via “create table as select”. You might ask, justifiably, why would you want to do that anyway? His problem was that the application has been split into 2 parts, and he wanted to have separate schemas for each part, to ensure that there is no cross-schema table access.
The way this should work is like this:
Oops! How could you do that without rebuilding the segments, I was wondering. And here’s what came up.
It’s not exactly rename t1 to kutrovsky.t1; , but it gets pretty close.
Let’s assume that t1 is the table we want to move. For demonstration purposes, allow me to create a simple table t1 :
The first step in our process is to create a range partitioned table, in the following example named t1_temp , based on the structure of our table. The name is of no importance, it is only temporary. We use any existing number, date or varchar2 column of our table for the partition key. The ranges also do not matter, since we’re not validating them.
As the second step, we create the new table, which will hold the data. Note that we’re only creating the layout, no data.
And now here comes the magical third step:
The first command “assigns” the data segment to the t1_temp table. The second command “assigns” the data segment to the t1 table in the new owner.
Magic? I don’t think so. Here’s how and why it works.
When you create a normal table, Oracle creates two items. The logical object ( object_id ) and the data segment ( data_object_id ). When you create a partitioned table, Oracle creates 1 logical object (the table) and multiple data segments (each partition). In a partitioned table, the logical object (the table) has no physical segment, only it’s partitions have them.
Oracle has a command to re-assign physical objects (data segments) to compatible logical objects, but it only works between a partition of a table and a non-partitioned table. When you use that command in the two step process as shown above, you essentially re-assign between two tables, by using a partitioned table to work around the limitation of the exchange command.
I took three snapshots of our objects of interest.
- Before executing any exchanges
- After 1st exchange
- After 2nd exchange
Notice how the data_object_id travels “down” and gets re-assigned.
OWNER | OBJECT_NAME | SUBOBJ | OBJECT_ID | DATA_OBJECT_ID |
---|---|---|---|---|
Before any exchange operations | ||||
BIG_SCHEMA | T1 | 673309 | 673309 | |
BIG_SCHEMA | T1_TEMP | T1 | 673312 | 673312 |
KUTROVSKY | T1 | 673313 | 673313 | |
alter table t1_temp exchange partition dummy with table t1 including indexes without validation; | ||||
BIG_SCHEMA | T1 | 673309 | 673312 | |
BIG_SCHEMA | T1_TEMP | T1 | 673312 | 673309 |
KUTROVSKY | T1 | 673313 | 673313 | |
alter table t1_temp exchange partition dummy with table kutrovsky.t1 including indexes without validation; | ||||
BIG_SCHEMA | T1 | 673309 | 673312 | |
BIG_SCHEMA | T1_TEMP | T1 | 673312 | 673313 |
KUTROVSKY | T1 | 673313 | 673309 |
This approach also works when the table has indexes. The little detail is that you have to create the same indexes on both the temp partitioned table (as local indexes!) and the final destination table.
Those of you who have been following along attentively will know that you can now drop the t1_temp table.
Эта статья посвящена сравнению эффективности различных способов переноса таблицы в другое табличное пространство. По мотивам ответа Тома Кайта на вопрос, первоначально заданный еще в апреле 2001 года.
Как выполняется alter table . move tablespace?
Не Мог бы ты разъяснить, как реализован оператор alter table t_name move tablespace . Это можно делать в оперативном режиме (online) и без журнализации (с опцией nologging). Но как данные переностяся из одного табличного пространства в другое? Приходится ли серверу формировать операторы insert и передавать данные через буферный кэш как при обычной вставке или происходит что-то типа непосредственной вставки?
Я столкнулся со следующей проблемой, для которой хотел бы найти быстрый способ решения:
Есть таблица размером 2,5 Гбайта. Я хочу перенести ее из табличного пространства a в b . Все файлы a и b разбиты на полосы и находятся на разных дисках. Эта таблица - независима. Я имею ввиду, что для нее не заданы триггеры и ограничения целостности.
Первый способ:
Второй способ:
Будет ли второй способ работать быстрее, чем первый, за счет использования непосредственной вставки?
Какой сопособ будет работать быстрее, и почему? Допускает ли первый способ распараллеливание? Булет ли существенная разница в использовании сегмента отката и пространства для сортировки?
Ответ Тома Кайта
Действие move в оперативном режиме может выполняться ТОЛЬКО для таблицы, организованной по индексу (index organized table - IOT), но не для обычной таблицы, организованной в виде кучи.
Имеет смысл делать так:
Оператор alter table t move tablespace b nologging; перенесет таблицу (с журнализацией, если она была установлена), а затем установит атрибут nologging .
При выполнении move для переноса таблицы SQL не используется. Никакие вставки не выполняются.
Такой перенос хорош тем, что все индексы, привилегии и т.п. остаются. Необходимо только перестроить (но не пересоздать) индексы после переноса.
Второй способ может сработать быстрее, если использовать параллельные вставки (проверьте, что для задания подсказок оптимизатору используется /*+ , а не просто /* .) Но для этого вам придется больше потрудиться. Для таблицы размером 2,5 Гбайт я не уверен, что оно того стоит - может потребоваться больше времени на разработку процедуры переноса, чем на сам перенос.
Перенос табличного пространства с опцией nologging
В Oracle Enterprise Edition 8.1.7.2 я делаю следующее:
Я не знаю, работает это с журнализацией или без, но после переноса таблица в режим nologging не переводится. А в версии Oracle 8.1.6 результат другой?
Ответ Тома Кайта
Хорошо, параметр logging / nologging имеет два значения, в зависимости от контекста.
В том контексте, где вы использовали его выше, вы попросили перенос выполнять без журнализации, если объект допускает работу без журналлизации.
Если выполнить оператор " alter table t nologging ", происходит изменение атрибута logging / nologging .
Как всегда, понять это поможет пример. Мы создадим таблицу, перенесем ее и посмотрим, сколько данных повторного выполнения будет сгенерировано при использовании различных методов переноса:
Итак, есть тестовая таблица. Она первоначально создана в табличном пространстве UTILS и:
ее режим журнализации - YES (журнализация установлена). Теперь давайте посмотрим, сколько данных повторного выполнения уже сгенерировал сеанс, и сохраним это значение в подставляемой переменной V
А теперь выполним вашу команду. Эту команду можно на русском языке сформулировать так: "Перенести таблицу T в табличное пространство users, и, кстати, если можно, БЕЗ ЖУРНАЛИЗАЦИИ". В частности, эта команда НЕ говорит: "Перенести таблицу и изменить режим журнализации".
Итак, мы видим, что сгенерировано порядка 4 Мбайт данных повторного выполнения - кажется, что действие, фактически, журнализируется. Это можно подтвердить, ИЗМЕНИВ режим журнализации:
и снова перенеся эту таблицу:
Теперь мы сгенерировали всего лишь 26 Кбайт данных повторного выполнения - этого достаточно для регистрации изменений в словаре данных, но не изменений перенесенных блоков. Мы перенесли объект без журнализации всех изменений.
Фактически мы выяснили, что нельзя одновременно переносить объект и изменять его любым другим способом (эти опции взаимоисключающие - вы либо переносите объект, либо изменяете его другим образом - одновременно это делать нельзя)
Можно ли восстановить действие, если используется nologging?
Если происходит сбой базы данных и придется восстанавливать ее после использования nologging для переноса, можно ли будет восстановить это действие. А после восстановления будет ли тавблица в исходном табличном пространстве?
Ответ Тома Кайта
Это зависит от причины сбоя и других обстоятельств.
После выполнения НЕ ЖУРНАЛИЗИРУЕМОГО действия в базе данных, работающей в режиме ARCHIVELOG (в котором и должны работать практически все производственные базы данных) рекомендуется выполнить горячее резервное копирование затронутых табличных пространств. Это позволит выполнить восстановление после сбоя носителя (media recovery) для этих табличных пространств.
Если этого не сделать И произойдет сбой носителя (а не просто сбой экземпляра) после выполнения не журнализируемого действия - данные будут потеряны. Их нельзя восстановить из архива, поскольку их в архиве нет. При выполнении действий без журнализации следует быть осторожным и согласовать действия с теми, кто отвечает за резервное копирование базы данных. В противном случае, легко потерять данные.
В базе данных, работающей в режиме noarchivelog , поскольку восстанавливаться можно только на момент последней полной резервной копии, выполненной в холодном режиме, при сбое носителя этот вопрос вообще не актуален (потому и надо работать в режиме archivelog !).
Что значит "таблица, огранизованная в виде кучи"?
Ответ Тома Кайта
Вот небольшая цитата из моей книги на эту тему, подробнее - читайте книгу ( Я привожу цитату по моему переводу на русский - В.К. ):
Таблицы, организованные в виде кучи
Таблицы, организованные в виде кучи, используются приложениями в 99 (если не более) процентах случаев, хотя со временем это может измениться за счет более интенсивного использования таблиц, организованных по индексу, - ведь по таким таблицам теперь тоже можно создавать дополнительные индексы. Таблица, организованная в виде кучи, создается по умолчанию при выполнении оператора CREATE TABLE . Если необходимо создать таблицу другого типа, это надо явно указать в операторе CREATE .
"Куча" - классическая структура данных, изучаемая в курсах программирования. Это по сути большая область пространства на диске или в памяти (в случае таблицы базы данных, конечно же, на диске), используемая произвольным образом. Данные размещаются там, где для них найдется место, а не в определенном порядке. Многие полагают, что данные будут получены из таблицы в том же порядке, в каком туда записывались, но при организации в виде кучи это не гарантировано. Фактически гарантировано как раз обратное: строки будут возвращаться в абсолютно непредсказуемом порядке. Это очень легко продемонстрировать. Создадим такую таблицу, чтобы в моей базе данных в блоке помещалась одна полная строка (я использую блоки размером 8 Кбайт). Совсем не обязательно создавать пример с одной строкой в блоке. Я просто хочу продемонстрировать предсказуемую последовательность событий. Такое поведение будет наблюдаться для таблиц любых размеров и в базах данных с любым размером блока:
.
Списки свободных мест
Я перенес таблицы в новое локально управляемое табличное пространство, а затем проанализировал таблицы. Мне интересно, почему столбец NUM_FREELIST_BLOCKS=0 в dba_tables ? Во всех таблицах есть неиспользуемые блоки, а в одном блоке - лишь несколько строк.
Ответ Тома Кайта
Потому, что блоки, в которых НИКОГДА не было данных, будут выше отметки максимального уровня, а не в списках свободных мест.
В списки свободных мест блоки попадают после использования - если они никогда не использовались, то в списке свободных мест их не будет.
Сразу после пересоздания, как в вашем случае, вполне естественно, что в списке свободных мест блоков МАЛО, если вообще они там есть. Это просто означает, что все существующие блоки данных "упакованы" - в них больше нельзя вставлять строки. После изменения/удаления данных некоторые блоки окажутся в списке свободных мест.
Рассмотрим следующий пример (табличное пространство system управляется по словарю, а табличное пространство users - локально управляемое):
Плотно упакованная таблица - никаких блоков в списке свободных мест пока нет.
А теперь - есть; мы добавили блоки в списки свободных мест, удалив некоторые строки.
Теперь их снова нет - все свободные блоки находятся выше отметки максимального уровня (HWM), а не в списках свободных мест.
а вот опять появились - таблица больше не "упакована", так как при удалении часть места освободилась
Перенос таблиц в 7.3.4 Parallel Server
Мы используем Oracle 7.3.4 Parallel Server в ОС NCR SVR4 (на неформатированных дисках). Я также использовал второй подход для переноса таблиц в другие табличные пространства, поскольку в версии 7.3.4 оператор alter table move tablespace . Я делал так:
Затем я снова создал индексы по таблице orgfoo . Мне хотелось бы знать:
a) Хорошее ли это решение для версии 7.3.4? Я нашел твое решение на сайте, где рекомендуется:
- Экспортировать схему пользователя
- Удалить все объекты пользователя
- Отобрать привилегию unlimited tablspace у пользователя
- Изменить стандартное табличное пространство для пользователя
- Импортировать данные пользователя
Но я хочу перенести только одну большую таблицу, а не все таблицы. После удаления всех объектов, как мне импортировать данные в два различных табличных пространства?
b) После переименования таблицы, надо ли пересоздать все представления до запуска приложения?
c) Для таблицы orgfoo (в табличном пространстве EHISTDAT ) выделено 250 Мбайт. Эту информацию я получил из dba_data_files и dba_free_space перед удалением таблицы orgfoo .
А при запросе после создания таблицы tempfoo в EKATSDAT и удаления таблицы orgfoo , я получил следующий результат:
Количество экстентов и блоков в представлении dba_extents тоже отличается. В табличном пространстве EHISTDAT освободилось 250 Мбайт, а в табличном пространстве было выделено не 250, а всего лишь 110 Мбайт. Не могли бы это объяснить? Считаете ли вы подобные действия полезными для экономии места на диске?
Ответ Тома Кайта
Ваш метод вполне приемлем. Можно сделать экспорт отдельной ТАБЛИЦЫ, а не всей схемы - это тоже подойдет, но и ваш метод отлично подходит (если только пересоздать все ограничения, триггеры, привилегии и т.п. - все это утилита EXP делает автоматически).
После переименования таблицы ничего делать не нужно. Представления сами о себе позаботятся, как и хранимые процедуры.
Что касается различия "размеров" - вновь созданная таблица заново "упакована". В результате, она вполне может оказаться "меньше". А вот насчет "полезности для экономии места" - я так не думаю. Через пару недель/месяцев таблица снова вырастет до прежнего размера. Это как когда садятся на диету - вес немного уменьшается, но в конечном итоге он снова увеличивается до "комфортного". Регулярная реорганизация таблиц:
a) мне не кажется нужной
b) мною не рекомендуется (при этом часто приходится слышать "блин, часть данных потеряна" из-за ошибок по ходу реогранизации)
c) место на диске "экономит" на пару дней, а со временем размер снова увеличивается до прежнего стабильного уровня.
Сбой экземпляра при переносе таблицы с опцией nologging
Что произойдет при сбое экземпляра по ходу переноса таблицы с опцией nologging? Мы данные не потеряем? Это не опасно?
Ответ Тома Кайта
Нет, nologging влияет только на восстановление после сбоя НОСИТЕЛЯ, но не после сбоя экземпляра.
При переносе таблицы с опцией nologging таблица копируется из постоянного сегмента во ВРЕМЕННЫЙ сегмент. В самом конце этого действия, временный сегмент преобразуется в постоянный - вото тогда копия и становится реальной таблицей.
Если сбой экземпляра произойдет по ходу переноса, процесс SMON просто очистит временный сегмент, и все будет выглядеть так, как если бы мы вообще таблицу не трогали (постоянный сегмент остается на месте).
Если сбой экземпляра произойдет после переноса - все в порядке, поскольку данные писались непосредственно на диск и восстанавливать их при восстановлении экземпляра не нужно.
Если после переноса часть данных изменена, изменение зафиксировано и произошел сбой - тоде все в порядке, поскольку данные повторного выполнения для этих изменений доступны и их можно восстановить.
Если после переноса и ДО резервного копирования файлов, которые были затронуты действием с опцией nologging произойдет СБОЙ ДИСКА - тогда да, "у нас проблемы". Вот почему в производственной среде есть основания опцию NOLOGGING не использовать, а если уж использовать, то:
- сначала создать резервную копию объектов;
- выполнить действие без журнализации;
- снова создать резервную копию объектов.
Итак, проблем при сбое экземляра вообще не возникает!
У меня есть вопрос вдогонку: поскольку вы сказали, что по ходу переноса постоянный сегмент не трогают, это означает, что запросы продолжают читать данные из постоянной таблицы, а не из временной, не так ли? А можно ли применять к таблице операторы ЯМД? Или таблица блокируется исключительной блокировкой?
Ответ Тома Кайта
Да, по ходу выполнения alter table move данные таблицы можно читать.
Выполнять операторы ЯМД можно только если действие выполняется "online" ( alter index rebuild online , например, alter table move online - но только для таблиц, организованных по индексу).
В Oracle9i есть пакет dbms_redefinition для пересоздания в режиме online большинства объектов (что позволяет выполнять операторы ЯМД по ходу переноса).
Комментарий читателя от 4 октября 2002 года
Я видел твой пример переноса таблицы. В нем вместо 4 Мбайт данных повторного выполнения (если при переносе была включена журнализация) генерировалось всего 26 Кбайт.
Я попытался сделать то же самое, но не увидел разницы. Не мог бы ты сказать, что я делаю не так. Вот мои результаты:
Как видишь, когда таблица журнализировалась, было сгенерировано 54320 байта данных повторного выполнения, в без журнализации - 53908 байт. Даже больше на 412 байт.
Я использую Oracle 8.1.7 на Windows 2000.
Ответ Тома Кайта
Вы работаете в режиме noarchivelog .
В этом режиме для этого действия не нужно генерировать данные повторного выполнения - вот они и не генерируются, независимо от установки logging/nologging.
Распараллеливание?
Итак, если необходимо "перенести" таблицу в другое табличное пространство (например, из управляемого по словарю в локально управляемое) быстрее будет использовать INSERT /*+ APPEND*/ , перевести таблицу в режим nologging , а не использовать move (с опцией nologging )?
А как насчет распараллеливания в Oracle 8.1.6 STANDARD? Можно ли использовать нечто вроде:
Команда работает, но я не знаю, как проверить, было ли распараллеливание при выполнении.
Посоветуйте, с точки зрения только производительности, что лучше - INSERT с APPEND nologging или move nologging .
Ответ Тома Кайта
Распараллеливание возможно только в EE и PE. См. в документации
Так что, в SE распараллеливание недоступно.
Но почему вам показалось, что insert /*+ append */ должно быть лучше?
Я бы просто перевел таблицу T в режим nologging и перенес ее:
Это проще, чем insert append , при этом не теряются привилегии и индексы.
(Пороверить, что действие распараллеливается, можно выполнив запрос к v$px_processes по ходу выполнения действия)
Комментарий читателя от 12 июня 2003 года
Я протестировал оба способа, но не в среде SQL*Plus, так что прощу прощения, что не могу просто вырезать и вставить "всю правду".
Я создал два табличных пространства. Я создал таблицу на базе dba_objects и удваивал ее пока в ней не оказалось ~ 1,8 миллиона строк. ~350 Мбайт при размере блока 16 Кбайт.
Затем я перевел таблицу в режим nologging (без распараллеливания).
Тестовая машина - двухпроцессорная, с Oracle 8.1.6 EE и обычными дисками (без RAID). При тестировании каждый тест выполнялся минимум дважды:
Если надо, я повторю эти же тесты в среде SQL*Plus и скопирую результаты.
Итак, почему insert /*+ append*/ выполняется быстрее, чем move ?
Данных повторного выполнения генерировалось от 200 до 350 Kбайт.
Ответ Тома Кайта
Я бы сказал, что разница между 137 и 125 секундами (общего времени выполнения) не существенна. 12 секунд ни о чем не говорят - особенно на компьютере, выполняющем еще какие-то действия.
Но, как показывапет ваш же тест, alter table move parallel 2 работает в 2 раза быстрее (первая попытка распараллеливания могла работать медленнее из-за того, что пришлось запускать дочерние процессы PQ - а поскольку запуск 4 процессов занял так много времени, возможно, были конфликты при доступе к исходному или целевому диску).
Я бы не делал на этом основании вывода, что insert append работает быстрее. Я бы сказал, что это намного сложнее, менее удобно, и вообще неправильно.
Комментарий читателя от 18 июня 2003 года
Интересно, раз таблица была перенесена, то ее индексы стали недействительными и их надо перестраивать, - а как индекс перестраивается? По таблице с новыми значениями rowid (я так думаю) или по существующему индексу (rowid в котором больше нельзя использовать).
Читайте также: