(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Особенности использования таблиц, организованных по индексу

Источник: ln

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

Повторное использование пространства в таблицах, организованных по индексу

Меня интересует, как повторно использовать пространство в таблице, организованной по индексу (Index Organized Table - IOT) после удаления существенного количества строк.

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

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

Ответ Тома Кайта

Ответ на этот вопрос, на самом деле, достаточно интересный - Oracle8i Release 8.1 позволяет выполнить два новых действия, которые делают ответ интересным:

  • оперативное пересоздание индексов;
  • перенос таблицы.

Поскольку таблица, организованная по индексу, - это просто индекс... Мы, фактически, можем пересоздать индекс путем переноса таблицы "на ходу" (т.е. пока происходит пересоздание пользователи изменяют данные таблицы...)

Вот пример:

ops$tkyte@dev8i> create table demo_iot
  2  ( object_id int primary key,
  3    oname     varchar2(30),
  4    owner     varchar2(30),
  5    status    varchar2(30) )
  6  organization index;

Table created.

ops$tkyte@dev8i> insert into demo_iot
  2  select object_id, object_name, owner, status
  3    from all_objects
  4  /

22525 rows created.

ops$tkyte@dev8i> column index_name new_value iname
ops$tkyte@dev8i> select index_name
  2    from user_indexes
  3   where table_name = 'DEMO_IOT'
  4  /

INDEX_NAME
------------------------------
SYS_IOT_TOP_87241

ops$tkyte@dev8i> analyze index &iname validate structure;
old   1: analyze index &iname validate structure
new   1: analyze index SYS_IOT_TOP_87241 validate structure
Index analyzed.

ops$tkyte@dev8i> select height, blocks, del_lf_rows from index_stats;

    HEIGHT     BLOCKS DEL_LF_ROWS
---------- ---------- -----------
         2        192           0

Теперь мы просто удалим примерно половину строк таблицы. Будем удалять строки "через одну".

ops$tkyte@dev8i> delete from demo_iot where mod(object_id,2) = 1;
11270 rows deleted.

ops$tkyte@dev8i> analyze index &iname validate structure;
old   1: analyze index &iname validate structure
new   1: analyze index SYS_IOT_TOP_87241 validate structure

Index analyzed.

ops$tkyte@dev8i> select height, blocks, del_lf_rows from index_stats;

    HEIGHT     BLOCKS DEL_LF_ROWS
---------- ---------- -----------
         2        192       11270

Итак, у нас в индексе достаточно много удаленных строк (ни один из блоков не стал полностью пустым). Как это "почистить"?

ops$tkyte@dev8i> alter table demo_iot move online;
Index altered.

ops$tkyte@dev8i> analyze index &iname validate structure;
old   1: analyze index &iname validate structure
new   1: analyze index SYS_IOT_TOP_87241 validate structure

Index analyzed.

ops$tkyte@dev8i> select height, blocks, del_lf_rows from index_stats;

    HEIGHT     BLOCKS DEL_LF_ROWS
---------- ---------- -----------
         2        128           0

Вот что мы получили - все "вычищено". В качестве теста, можете оставить открытыми другие сеансы, пока выполняется alter table move - просто чтобы убедиться, что таблица доступна для запросов и всех операторов DML.

Комментарий читателя от 23 августа 2001 года

Вы говорили про два метода. Один из них - оперативное пересоздание индекса.

Я попробовал его применить, но ничего не получилось.

alter index SYS_IOT_TOP_87241 rebuild
*
ERROR at line 1:
ORA-28650: Primary index on an IOT cannot be rebuilt

Ответ Тома Кайта

См. http://download-east.oracle.com/docs/cd/A81042_01/DOC/server.816/a76956/tables.htm#1913

Это делается с помощью оператора:

ALTER TABLE docindex MOVE ONLINE;

Изменение первичного ключа таблицы, организованной по индексу

Если, скажем, у меня есть организованная по индексу таблица T со столбцами a, b, c, d, причем, столбцы a,b образуют первичный ключ.

Мне же нужно, чтобы первичным ключом были столбцы a,b,c. Нет ли оператора alter table, позволяющего изменить таблицу, организованную по индексу, и добавить еще один столбец в составной первичный ключ?

Ответ Тома Кайта

В Oracle9i можно использовать оперативное пересоздание.

В 8i, придется использовать Create table ... as select ..., удалить старую таблицу и переименовать новую.

Префикс...

Если, скажем, у меня есть организованная по индексу таблица T со столбцами a, b, c, d... Но теперь первичный ключ образуют столбцы a, b, c, именно в таком порядке.

Я обнаружил, что в большинстве запросов у меня используется условие по столбцам a,c. Будет ли при этом полезен составной ключ по столбцам a,b,c? По сравнению с составным ключом по столбцам a,c?

Ответ Тома Кайта

Первичный ключ - это первичный ключ, это его основное свойство.

Если в большинстве запросов обращение к таблице идет по столбцам a,c, то первичный ключ должен быть по столбцам a,c,b

Вопрос вдогонку...

Половина моих запросов - по a,c, а другая половина - по a,b.

Если создать составной первичный ключ по столбцам a,b,c, будет ли он использоваться для всех этих запросов? По a,b запросов немного больше, чем по a,c.

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

Система относится к классу 24x7, и время простоя надо свести к минимуму.

Как мне заморозить упомянутую таблицу? Нет ли оператора "alter table <имя_таблицы> read only" - не могу его найти в 8i. Или исходная табллица будет заморожена оператором create table ... as select ...?

Я собираюсь в периоды минимальной нагрузки сделать следующее:

  1. переименовать таблицу в <temp>- чтобы дальнейшие изменения не происходили
  2. create table <исходная таблица> as select from <temp>

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

Ответ Тома Кайта

В одном сеансе:

lock table t in exclusive mode;

а в другом скопируйте ее.

Потом в первом сеансе удалите, а новую таблицу переименуйте.

В 8i, если запросы выбирают данные по a,b и a,c, скорее всего, надо создать индексы по:

a,b,c
c

Отдельно по столбцу "c" потому, что все индексы таблицы, организованной по индексу, и так включают первичный ключ. Рассмотрим пример:

ops$tkyte@ORA817DEV> create table t (a int, b int, c int, d char(20), 
primary key (a,b,c) ) organization index;

Table created.

ops$tkyte@ORA817DEV> insert into t
  2  select rownum, -rownum, rownum*2, 'x'
  3  from all_objects where rownum <= 5000;

5000 rows created.

ops$tkyte@ORA817DEV> create index t_idx on t(c);

Index created.

ops$tkyte@ORA817DEV> analyze table t compute statistics for table for all 
indexes for all indexed columns;

Table analyzed.

ops$tkyte@ORA817DEV> set autotrace traceonly explain
ops$tkyte@ORA817DEV> select a,c from t where c = 44 and a = 22;

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1 Bytes=6)
   1    0   INDEX (RANGE SCAN) OF 'T_IDX' (NON-UNIQUE) (Cost=1 Card=1 Bytes=6)

ops$tkyte@ORA817DEV> set autotrace off

Видите, как удалось выполнить запрос исключительно по индексу? Для получения значения A вообще не пришлось обращаться к таблице, - оно есть в индексе.

Требуется ли пересоздание индекса?

Почему мы должны пересоздавать индексы?. Вы же против пересоздания индексов. Вот ваш ответ:

http://asktom.oracle.com/pls/ask/f?p=4950:8:444551828551181757::NO::F4950_P8_DISPLAYID,F4950_P8_CRITERIA:6601312252730,

Прокомментируйте, пожалуйста.

Ответ Тома Кайта

Я НЕ ПРОТИВ пересоздания вообще.

Я - против регулярного пересоздания индексов лишь потому, что "все знают, что так надо делать".

Я против выполнения действий, про которые не известно, что они:

  • делают систему лучше;
  • не вызывают негативных последствий.

Индексы на основе битовых карт (bitmap indexes) могут потребовать пересоздания после выполнения некоторого количества операторов DML.

Мой текстовый индекс на сайте asktom - я его время от времени пересоздаю, после существенного изменения данных (фактически, он очень похож на bitmap index).

Индексы на основе b*-деревьев - вряд ли их вообще когда-либо стоит пересоздавать (подсказка: почитайте про COALESCE, - дает большинство тех же преимуществ, а работы намного меньше).

Комментарий читателя от 16 июля 2003 года

Я создал таблицу, организованную по индексу, для использования в качестве выпадающего списка:

create table category
  (name VARCHAR2(50)
     CONSTRAINT category$name$nn NOT NULL
  ,display_yn VARCHAR2(1)     
     CONSTRAINT category$display$nn NOT NULL
  ,CONSTRAINT category$pk 
     PRIMARY KEY (name)
  ) 
  organization index tablespace indx
  including display_yn overflow;

alter table category add constraint category$display$ck01
  check(display_yn in ('Y','N'));

create unique index category$name$x on category(UPPER(name))
  tablespace indx;

Меня интересует следующее:

1. По сути, есть два индекса по одному столбцу таблицы. Эффективно ли это, и как бы обойтись одним индексом?

NEREUS@mdl1> select index_name, index_type from dba_indexes
  2  where owner='NEREUS' and index_name like 'CATEGORY%';

INDEX_NAME                     INDEX_TYPE
------------------------------ ---------------------------
CATEGORY$NAME$X                FUNCTION-BASED NORMAL
CATEGORY$PK                    IOT - TOP

2. Как задать явное имя для таблицы переполнения (OVERFLOW)?

NEREUS@mdl1> select table_name, iot_name from dba_tables
  2  where owner='NEREUS'
  3  and table_name='CATEGORY'
  4  or IOT_NAME='CATEGORY';

TABLE_NAME                     IOT_NAME
------------------------------ -----------------------------
CATEGORY
SYS_IOT_OVER_27251             CATEGORY

Хотелось бы также узнать ваши рекомендации по повышению производительности.

Ответ Тома Кайта

1) На самом деле, я вижу только ОДИН индекс, - по функции, который вы создали. Другой "индекс" - это, фактически, сама таблица.

2) Сегмент переполнения в этот случае не нужен и нежелателен. Фактически, я бы сказал, что, если вам нужен сегмент переполнения, то вам вряд ли нужна организация таблицы по индексу (бывают, конечно, и исключения).

Если вы всегда ищете строку в верхнем регистре, можно создать таблицу:

create table category
  (upper_name varchar2(50) constraint cat$pk primary key,
   name VARCHAR2(50)  CONSTRAINT category$name$nn NOT NULL,
   display_yn VARCHAR2(1) CONSTRAINT category$display$nn NOT NULL
  ) 
  organization index;

и просто вставлять в нее имя в верхнем регистре, имя и display_yn.

При этом вы получаете:

  • одну лишь таблицу, организованную по индексу;
  • никаких двусмысленностей, потому что сейчас у вас в качестве значения "первичного ключа" таблицы может быть как 'hello', так и 'Hello'.

    Как сервер находит строку в таблице, организованной по индексу

    Использует ли сервер значение первичного ключа для быстрого поиска строки в таблице, организованной по индексу? Он же не хранит rowid, как в обычном индексе на основе b-дерева? Не могли бы вы объяснить, какой механизм используется.

    Ответ Тома Кайта

    Хранится "rowid", но универсальный, а не физический. И он, фактически, включает значение первичного ключа. Рассмотрим пример:

    ops$tkyte@ORA920> create table t ( x varchar2(50) primary key ) organization index;
    
    Table created.
    
    ops$tkyte@ORA920> insert into t values ( 'xxx' );
    
    1 row created.
    
    ops$tkyte@ORA920> insert into t values ( rpad('x',50,'x') );
    
    1 row created.
    
    ops$tkyte@ORA920> select x, rowid from t;
    
    X                                                  ROWID
    -------------------------------------------------- 
    -------------------------------------------------------------------------------
    xxx                                                *BAGAAjoDeHh4/g
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 
    *BAGAAjoyeHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHj+
    

    видите, каким большим может быть rowid...

    Ключ индекса содержит...

    Значит ли это, что в записи индекса по столбцу (вторичного индекса) будет значение ключа, значение первичного ключа и rowid (логический)?

    Ответ Тома Кайта

    Да. Обратите внимание, как в следующем примере обращение идет только к индексу T_IDX, а к таблице вообще не обращаются. Хотя индекс - только по столбцу Y.

    ops$tkyte@ORA920> create table t ( x int primary key, y int ) organization index;
    
    Table created.
    
    ops$tkyte@ORA920> create index t_idx on t(y);
    
    Index created.
    
    ops$tkyte@ORA920> exec dbms_stats.set_table_stats( user, 'T', numrows => 100000 );
    
    PL/SQL procedure successfully completed.
    
    ops$tkyte@ORA920> set autotrace traceonly explain
    ops$tkyte@ORA920> select x from t where y = 1;
    
    Execution Plan
    ----------------------------------------------------------
       0      SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1000 Bytes=26000)
       1    0   INDEX (RANGE SCAN) OF 'T_IDX' (NON-UNIQUE) (Cost=2 Card=1000 
    Bytes=26000)
    
    ops$tkyte@ORA920> select y from t where y = 1;
    
    Execution Plan
    ----------------------------------------------------------
       0      SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1000 Bytes=13000)
       1    0   INDEX (RANGE SCAN) OF 'T_IDX' (NON-UNIQUE) (Cost=2 Card=1000 
    Bytes=13000)
    
    ops$tkyte@ORA920> select rowid from t where y = 1;
    
    Execution Plan
    ----------------------------------------------------------
       0      SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1000 Bytes=30000)
       1    0   INDEX (RANGE SCAN) OF 'T_IDX' (NON-UNIQUE) (Cost=2 Card=1000 
    Bytes=30000)
    

    Размер таблицы, организованной по индексу

    Я занимаюсь преобразованием некоторых "больших, но тощих" таблиц из более чем 10000 строк в организованные по индексу и обнаружил, что это существенно повышает производительность.

    Как вы думаете, имеет ли смысл организовывать по индексу таблицы из менее чем 10000 строк? Даст ли это существенное преимущество по сравнению с обычной таблицей с индексами?

    Ответ Тома Кайта

    Да, несомненно. При поиске по ключу может потребоваться всего 1/3 операций логического ввода-вывода. Если такой поиск выполняется часто, 100 строк в таблице или 10000 - не важно.

    COALESCE или MOVE ONLINE

    1) Когда использовать ALTER iot_table COALESCE, а когда - ALTER iot_table MOVE ONLINE? Есть ли случаи, когда использование COALESCE оправдано?

    2) Если по таблице iot_table есть индекс и мы выполняем MOVE ONLINE, надо ли пересоздавать этот индекс?

    Ответ Тома Кайта

    1) Используйте coalesce для "сжатия" таблицы, организованной по индексу.

    Используйте move для ее переноса. При этом происходит полное пересоздание и требуется свободное пространство размером с таблицу.

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

    ops$tkyte@ORA920LAP> create table heap( x int primary key, y int );
    
    Table created.
    
    ops$tkyte@ORA920LAP> create index heap_idx on heap(y);
    
    Index created.
    
    ops$tkyte@ORA920LAP> create table iot( x int primary key, y int ) organization index;
    
    Table created.
    
    ops$tkyte@ORA920LAP> create index iot_idx on iot(y);
    
    Index created.
    
    ops$tkyte@ORA920LAP> insert into heap select rownum, rownum from all_objects;
    
    30694 rows created.
    
    ops$tkyte@ORA920LAP> insert into iot  select rownum, rownum from all_objects;
    
    30694 rows created.
    
    ops$tkyte@ORA920LAP> analyze table heap compute statistics for table;
    
    Table analyzed.
    
    ops$tkyte@ORA920LAP> analyze table iot  compute statistics for table;
    
    Table analyzed.
    
    ops$tkyte@ORA920LAP> set autotrace on explain
    ops$tkyte@ORA920LAP> select * from heap where y = 55;
    
             X          Y
    ---------- ----------
            55         55
    
    Execution Plan
    ----------------------------------------------------------
       0      SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=307 Bytes=3684)
       1    0   TABLE ACCESS (BY INDEX ROWID) OF 'HEAP' (Cost=2 Card=307 Bytes=3684)
       2    1     INDEX (RANGE SCAN) OF 'HEAP_IDX' (NON-UNIQUE) (Cost=1 Card=123)
    
    ops$tkyte@ORA920LAP> select * from iot  where y = 55;
    
             X          Y
    ---------- ----------
            55         55
    
    Execution Plan
    ----------------------------------------------------------
       0      SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=307 Bytes=4298)
       1    0   INDEX (RANGE SCAN) OF 'IOT_IDX' (NON-UNIQUE) (Cost=1 Card=307 
    Bytes=4298)
    
    ops$tkyte@ORA920LAP> set autotrace off
    ops$tkyte@ORA920LAP> alter table heap move;
    
    Table altered.
    
    ops$tkyte@ORA920LAP> alter table iot  move online;
    
    Table altered.
    
    ops$tkyte@ORA920LAP> set autotrace on explain
    ops$tkyte@ORA920LAP> select * from heap where y = 55;
    select * from heap where y = 55
    *
    ERROR at line 1:
    ORA-01502: index 'OPS$TKYTE.HEAP_IDX' or partition of such index is in unusable 
    state
    
    ops$tkyte@ORA920LAP> select * from iot  where y = 55;
    
             X          Y
    ---------- ----------
            55         55
    
    Execution Plan
    ----------------------------------------------------------
       0      SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=307 Bytes=4298)
       1    0   INDEX (RANGE SCAN) OF 'IOT_IDX' (NON-UNIQUE) (Cost=1 Card=307 
    Bytes=4298)
    

    Индексы обычной таблицы надо пересоздавать (изменились физические идентификаторы строк), а индексы таблицы, организованной по индексу - нет.

    Индекс с большим размером блока

    SQL> Select Tablespace_name,block_size from Dba_Tablespaces
      2  /
    
    TABLESPACE_NAME                BLOCK_SIZE
    ------------------------------ ----------
    ....
    TEST                                 2048
    SIXTEEN_K                           16384
    
    6 rows selected.
    
    SQL> Alter user j default tablespace test;
    
    SQL> create table a(  a  varchar2(700) primary key )
         organization index;
    
    Table created.
    
    SQL> alter table a modify (a   varchar2(4000));
    alter table a modify (a   varchar2(4000))
                          *
    ERROR at line 1:
    ORA-01404: ALTER COLUMN will make an index too large  <<--
    
    SQL> Select index_name,table_name,tablespace_name from user_indexes;
    
    INDEX_NAME         TABLE_NAME  TABLESPACE_NAME
    ------------------ ----------- ----------------
    SYS_IOT_TOP_25958  A           TEST     <<--- 2k Tablespace
    
    SQL> Alter table a move tablespace sixteen_k;
    
    Table altered.
    
    SQL> select index_name,table_name,tablespace_name from user_indexes ;
    
    INDEX_NAME        TABLE_NAME TABLESPACE_NAME
    ----------------- ---------- ---------------
    SYS_IOT_TOP_25958 A          SIXTEEN_K
    
    SQL> alter table a modify (a   varchar2(4000));
    
    Table altered.
    
    SQL> alter table a move tablespace test ;   <<--- Moving back in 2k
    
    Table altered.
    
    SQL> select index_name,table_name,tablespace_name from user_indexes ;
    
    INDEX_NAME        TABLE_NAME TABLESPACE_NAME
    ----------------- ---------- ---------------
    SYS_IOT_TOP_25958 A          TEST   ??????
    

    Как одна запись индекса может иметь размер более 4000 байтов при размере блока 2 Кбайта?

    Ответ Тома Кайта

    Похоже на ошибку, они забыли проверить... Если в таблице есть строки, превышающие максимальный размер, вы должны были получить:

    alter table t move tablespace ts_2k
                *
    ERROR at line 1:
    ORA-00600: internal error code, arguments: [17023], [0x5CC5E94C], [], [], [], 
    [], [], []
    

    если alter move успешно сработает, вы получите:

    insert into t values ( rpad('*',4000,'*') )
                *
    ERROR at line 1:
    ORA-00600: internal error code, arguments: [kdisle:nrows], [1], [], [], [], [], 
    [], []
    

    при попытке вставить очень большую строку.

    При этом никакого повреждения данных и т.п. не происходит - просто пропущена проверка перед переносом. Я уже выставил ошибку по мотивам вашего сообщения со следующим тестовым примером:

    create tablespace ts_2k datafile size 1m blocksize 2k;
    create tablespace ts_16k datafile size 1m blocksize 16k;
                                                                                     
    create table t ( x varchar2(500) primary key )
    organization index tablespace ts_2k;
                                                                                     
    alter table t modify x varchar2(4000);
                                                                                     
    alter table t move tablespace ts_16k;
                                                                                     
    alter table t modify x varchar2(4000);
                                                                                     
    insert into t values ( rpad('*',4000,'*') );
    
    alter table t move tablespace ts_2k;
    delete from t;
    
    alter table t move tablespace ts_2k;
    insert into t values ( rpad('*',4000,'*') );
    

    Как можно обычную таблицу сделать организованной по индексу?

    Организация таблицы по индексу кажется подходящей в моем случае. У нас в таблице - 6 миллионов строк, обращение к которым всегда идет по одному индексу; в таблице всего пять столбцов, и по 3 создается индекс, так что, организация таблицы по индексу кажется прекрасным решением. Но у меня есть два вопроса.

    Как реально "реорганизовать" эту таблицу по индексу? Если создать новую таблицу и выполнить: insert into ... select * ... при шести миллионах строк, эта операция рано или поздно закончится неудачно (после того, как будут заняты все сегменты отката). Нет ли более интересного способа изменить организацию таблицы? А если нет, что, если я экспортирую таблицу, удалю ее, создам таблицу с таким же именем, но другой организацией... Сработает ли импорт? Нет ли причины (интенсивные вставки/изменения...), по которой не стоит использовать организацию таблицы по индексу?

    И еще вопрос: можно ли секционировать таблицу, организованную по индексу? В этом, вообще, есть смысл?

    Ответ Тома Кайта

    Все закончится удачно, если задать размер сегментов отката в соответствии с теми действиями, которые надо выполнить (ради бога, я часто с 10 миллионами и больше "широких" строк работаю на своем ноутбуке. На ноутбуке!)

    Вы можете секционировать таблицу, организованную по индексу, да.

    Да, в этом есть смысл (но 6 миллионов строк, все равно, это немного)

    Если использовать:

    "CREATE TABLE IOT ( columns..., primary key(...) ) organization index
    as
    select...."
    

    то окажется, что используется, примерно, аж один блок в сегменте отката :) Вы беспокоитесь о том, что не должно произойти (а в режиме archive log вы можете выполнять это действие в режиме nologging, согласовав с АБД выполнение резервного копирования этих новых данных как можно скорее, и устранить тем самым любые проблемы с журналом повторного выполнения, которые вы могли себе надумать):

    big_table@ORA9IR2> desc test
     Name                          Null?    Type
     ----------------------------- -------- --------------------
     ID                                     NUMBER
     OBJECT_ID                     NOT NULL NUMBER
     CREATED                       NOT NULL DATE
     OWNER                         NOT NULL VARCHAR2(30)
     OBJECT_NAME                   NOT NULL VARCHAR2(30)
     
    big_table@ORA9IR2> select count(*) from test;
     
      COUNT(*)
    ----------
       6000000
    
    big_table@ORA9IR2> create table iot
      2  ( id, object_id, created, owner, object_name, primary key(id,object_id,created))
      3  organization index
      4  as
      5  select * from test;
     
    Table created.
     
    Elapsed: 00:04:21.35
    

    и использован был один блок UNDO!

    Секционированная по диапазону, организованная по индексу сжатая таблица

    В 9iR2 у меня есть таблица из 3 столбцов, с, примерно, миллиардом строк, да еще и быстро растущая. Я хотел бы секционировать ее по диапазону, сжать и организовать по индексу.

    Я не слишком многого хочу? :-)

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

    Я займусь тестированием надежности/скорости и других аспектов сжатия данных в таблице (уже организованной так, как описано выше), но основной вопрос в том, является ли такое решение (если тестирование даст положительные результаты) стабильным и подходящим для "промышленного" использования? Т.е. нет ли известных ошибок, "нюансов" или других проблем, которые могут стать осущественным препятствием или существенной угрозой в будущем.

    Ответ Тома Кайта

    3 "узких" столбца = замечтаельно для таблицы, организованной по индексу

    1,000,000,000 rows = подходящая кандидатура на секционирование

    Если начальные столбцы имеют много повторяющихся значений, то сжатие = вполне неплохая идея...

    Я не знаю ни про какие "нюансы" и потенциальные проблемы, которые не позволяют это делать.

    Чтоы удостоверится...

    Спасибо за ответ, но я хочу удостоверится, что правильно описал ситуацию, потому что это критически важно в нашем случае:

    Я хочу использовать ОРГАНИЗОВАННУЮ ПО ИНДЕКСУ, СЕКЦИОНИРОВАННУЮ ПО ДИАПАЗОНУ и СЖАТУЮ таблицу, приметрно такую, как создается ниже (я где-то нашел синтаксис для сжатия) [кстати, спасибо за подсказку о "начальных столбцах с повторяющимися значениями"]

    Мне на мгновение показалось, если я правильно понял, что вы оправдываете использование секционированной ИЛИ организованной по индексу таблицы, но я хочу и то, и другое, И сжатие, но озабочен вероятностью потери данных и т.п. в долгосрочной перспективе. У нас памяти - вагон, так что время на сжатие меня не беспокоит, хотя, протестировать надо. Меня больше беспокоит повреждение данных и т.п., ПЛЮС если будет выполнен TRUNCATE (как я случайно сделал, пока разбирался, как выполнить усечение для секции)  - придется ли мне пересоздавать ВСЮ таблицу или только эту организованную по индексу секцию :-)

    Был ли представленный выше сценарий опробован серьезными компаниями успешно и без особых проблем для администрирования?

    create table myparttable         
        (        
          field1        number(10),    
          field2       number(10),    
          field3       number(10),        
       constraint table_pk primary key (field1,field2,field3)
         organization index nologging    
        partition by range(field1)     
        (partition p7 values less than  (8) tablespace ля-ля-ля.....
    

    ... (Вопрос про 10g выкинут, поскольку Том на него не ответил, пока. - Прим. В.К. )

    Ответ Тома Кайта

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

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

    Оригинал обсуждения этого вопроса можно найти здесь.

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 08.04.2010 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Oracle Database Personal Edition Named User Plus License
Oracle Database Standard Edition 2 Processor License
Oracle Database Personal Edition Named User Plus Software Update License & Support
Oracle Database Standard Edition 2 Named User Plus License
AutoCAD LT 2022 Commercial New Single-user ELD Annual Subscription
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
Реестр Windows. Секреты работы на компьютере
СУБД Oracle "с нуля"
Каждый день новые драйверы для вашего компьютера!
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100