Изменение первичного ключа

#oracle #plsql #ddl

#Oracle #plsql #ddl

Вопрос:

Я видел 2 подхода к изменению первичного ключа. подход 1 — это то, при котором я удаляю первичный ключ (он также удаляет соответствующий индекс), а затем создаю первичный ключ с новым индексом в нем, т.е.

 alter table TABLE_NAME drop constraint PK_TABLE_NAME drop index;
alter table TABLE_NAME
add constraint PK_TABLE_NAME PRIMARY KEY ("COL1") 
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 
           PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT) 
  TABLESPACE "USERS" ENABLE;
COMMIT;
/
  

Второй подход заключается в выполнении всех шагов по отдельности, т.е.

 alter table TABLE_NAME drop constraint PK_TABLE_NAME;
drop index PK_TABLE_NAME;

CREATE UNIQUE INDEX PK_TABLE_NAME ON TABLE_NAME
(COL1)
LOGGING
TABLESPACE USERS
PCTFREE    10
INITRANS   2
MAXTRANS   255
STORAGE    (
            INITIAL          64K
            MINEXTENTS       1
            MAXEXTENTS       UNLIMITED
            PCTINCREASE      0
            BUFFER_POOL      DEFAULT
            FLASH_CACHE      DEFAULT
            CELL_FLASH_CACHE DEFAULT
           )
NOPARALLEL;

alter table TABLE_NAME add constraint PK_TABLE_NAME PRIMARY KEY ("COL1") USING INDEX PK_TABLE_NAME;
COMMIT;
/
  

Итак, теперь мои вопросы

  1. имеют ли эти 2 подхода что-то другое в серверной части, за исключением того факта, что шаги разделены?
  2. Я вижу, что мы можем указать имя столбца в кавычках, т.е. «COL1» или без кавычек, т.е. COL1. Будут ли эти 2 подхода иметь какое-либо значение?
  3. Рассмотрим, что эти шаги выполняются в таблице с ТРИЛЛИОНАМИ ДАННЫХ, имеет ли какой-либо из них какой-либо прирост производительности по сравнению с другими?

Ответ №1:

Насколько я знаю, между ними нет разницы с DDL точно таким, какой он у вас есть. (Это основано на сравнении select dbms_metadata.get_ddl('TABLE', 'TABLE_NAME') from dual; , некоторых простых тестах производительности и моем предыдущем опыте работы с этими двумя подходами.)

Но если у вас есть триллионы строк или байтов, тогда вам, вероятно, следует использовать параллелизм, и тогда есть существенная разница. Первый подход не позволяет вам создавать индекс параллельно ( ORA-03001: unimplemented feature ), но второй метод позволяет. Даже если вы не хотите, чтобы индекс был параллельным, вам, вероятно, следует создать его параллельно, а затем изменить его на noparallel с помощью команды типа ALTER INDEX <index> NOPARALLEL;


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


Несколько других замечаний. Возможно, вы захотите рассмотреть возможность использования NOLOGGING. И в этом нет необходимости COMMIT; , DDL автоматически вызовет фиксацию.

Комментарии:

1. Мне понравилось использование ‘parallel’ при создании индекса во втором подходе.

2. PARALLEL отлично подходит для создания индекса в очень больших таблицах, просто имейте в виду, что у него есть побочный эффект, заключающийся в том, что в индексе остается «параллельный» бит, установленный в индексе. Чтобы отменить это после создания индекса, вам необходимо ALTER INDEX <index> NOPARALLEL;

3. @deleto Спасибо, я добавил ваш фрагмент кода к своему ответу.