Настало, наконец, время заняться серьезными вещами! :) Любая операция ввода-вывода, о которой мы говорили ранее, как следствие влечет за собой фрагментацию табличного пространства. Еще ее можно назвать фрагментацией экстентов (extent fragmentation). Возникает она при изменении размещения экстентов в табличном пространстве. Может происходить либо за счет фрагментации свободного пространства, либо за счет фрагментации таблиц. Как правило следует избегать размещения в одном разделе таблиц с разными уровнями активности. Экстент можно назвать свободным (free extents), если он никогда не выделялся для сегментов табличного пространства, либо был освобожден в результате удаления сегментов. Фрагментации экстентов бывают разных типов. Например, если изолированные наборы свободных экстентов, распределены по всему табличному пространству, то такая фрагментация называется - фрагментация типа "швейцарский сыр" (Swiss cheese fragmentation) или пузырьковой фрагментацией (bubbling). При наличии смежных свободных экстентов, которые распределены по всему свободному табличному пространству - фрагментация называется - "сотовой фрагментацией" (honeycomb fragmentation). Каждый из этих двух типов фрагментации является - "фрагментацией со свободными экстентами" (free space fragmentation). Существует так же и - "фрагментация таблиц" (table fragmentation), то есть динамическое расширение таблицы за пределы ее исходных экстентов. Из всего вышесказанного ясно, что чрезмерная фрагментация приводит к замедлению вашей БД. Так как для поисков разрозненных участков, например таблицы при проведении запроса к ней может потребовать существенно большего времени, в отличие от таблицы расположенной одним "не равным" экстентом! Надеюсь это понятно!
Давайте углубимся в это еще немного! В жизни это вам пригодится! Итак, создается табличное пространство. В нем создается сегмент имеющий, скажем, один экстент состоящий из n-блоков Oracle! Ясно? Вот так весь этот механизм строится. Сегмент так же может состоять из нескольких разделов - экстентов. Еще раз повторюсь сами по себе экстенты представляют собой группы смежных блоков Oracle. Когда уже существующий экстент уже не может вместить в себя данные - сегмент получает еще один экстент. Вот так! Процесс продолжается до тех пор пока в файле данных не останется больше места, либо пока не будет достигнуто внутреннее максимальное количество экстентов на сегмент! Уловили? Для упрощения управления сегментами лучше, чтобы каждый сегмент данных содержал по одному экстенту! Вот по этому параметр хранения сегмента - initial определяющий размер начального экстента должен быть достаточно большим, чтобы обработать все данные сегмента! Кстати, если сегмент состоит из нескольких экстентов, то это не дает гарантии, что они расположены рядом друг с другом. Для примера можно сказать, что выполнить операцию DROP TABLE для таблицы содержащей, скажем, 3000 экстентов при хорошем стечении обстоятельств может занять 5-10 мин. А вот попробуйте удалить дефрагментированную таблицу в 60 000 экстентов, для этого Вам понадобится целый день! Давайте посмотрим, как себя чувствует наша учебная табличка CUSTOMERS? Дадим вот такой запрос:
SELECT TABLESPACE_NAME, OWNER, SEGMENT_NAME, SEGMENT_TYPE, EXTENTS, BLOCKS, BYTES FROM DBA_SEGMENTS WHERE TABLESPACE_NAME = 'USERS' AND SEGMENT_NAME = 'CUSTOMERS' AND OWNER = 'MILLER' /
Получаем:
SQL> SELECT TABLESPACE_NAME, 2 OWNER, 3 SEGMENT_NAME, 4 SEGMENT_TYPE, 5 EXTENTS, 6 BLOCKS, 7 BYTES 8 FROM DBA_SEGMENTS 9 WHERE TABLESPACE_NAME = 'USERS' AND 10 SEGMENT_NAME = 'CUSTOMERS' 11 AND OWNER = 'MILLER' 12 / TABLESPACE_NAME OWNER SEGMENT_NAME SEGMENT_TYPE EXTENTS BLOCKS BYTES --------------- ------- ------------- ------------ ---------- ---------- ---------- USERS MILLER CUSTOMERS TABLE 2 16 131072
Да! результат не веселый! Хотя бы тот факт, что табличка уже размазалась по двум экстентам! Да размерчик у нее что-то больно велик. Так вот для того, чтобы уменьшить "расходы" при работе с сильно фрагментированными таблицами в Oracle 8i и старше введены локально управляемые табличные пространства! (locally managed tablespaces), в которых информация об использовании экстентов хранится в битовой карте в заголовке файла данных, а не в словаре данных. Вот так и решили проблему. А, теперь давайте посмотрим информацию об экстентах одного сегмента данных. Все той же нашей таблички CUSTOMERS. Дадим вот такой запрос:
SELECT TABLESPACE_NAME, OWNER, SEGMENT_NAME, SEGMENT_TYPE, EXTENT_ID, BLOCK_ID, BYTES BLOCKS FROM DBA_EXTENTS WHERE TABLESPACE_NAME = 'USERS' AND SEGMENT_NAME = 'CUSTOMERS' AND OWNER = 'MILLER' /
Получаем:
SQL> SELECT TABLESPACE_NAME, 2 OWNER, 3 SEGMENT_NAME, 4 SEGMENT_TYPE, 5 EXTENT_ID, 6 BLOCK_ID, 7 BYTES 8 BLOCKS 9 FROM DBA_EXTENTS 10 WHERE TABLESPACE_NAME = 'USERS' 11 AND SEGMENT_NAME = 'CUSTOMERS' 12 AND OWNER = 'MILLER' 13 / TABLESPACE_NAME OWNER SEGMENT_NAME SEGMENT_TYPE EXTENT_ID BLOCK_ID BLOCKS --------------- ------ ------------ ------------- --------- --------- ------- USERS MILLER CUSTOMERS TABLE 0 41 65536 USERS MILLER CUSTOMERS TABLE 1 49 65536
В вашем случае информация может и отличаться, но мой сервер по такому запросу дает именно это! Как можно видеть таблица находится в двух экстентах. Само собой напрашивается вопрос "как же все-таки решать проблему дефрагментации табличных пространств"? А, вот с этим мы далее и разберемся! А, пока усваивайте выше изложенное.