Як це реалізовано, Oracle, Бази даних, статті

Можливість стиснення таблиць в Oracle9i Release 2 реалізується шляхом видалення дубльованих значень даних з таблиць бази. Стиснення виконується на рівні блоків бази даних. Коли таблиця визначена як стисла, сервер резервує місце в кожному блоці бази даних для зберігання однієї копії даних, що зустрічаються в цьому блоці в декількох місцях. Це зарезервоване місце називають таблицею символів (symbol table). Помічені для стиснення дані зберігаються тільки в таблиці символів, а не в рядках даних. При появі в рядку даних, помічених для стиснення, в рядку, замість самих даних, запам’ятовується покажчик на відповідні дані в таблиці символів. Економія місця досягається за рахунок видалення надлишкових копій значень даних у таблиці.

Стиснення таблиці на користувача або розробника додатків ніяк не впливає. Розробники звертаються до таблиці однаково, незалежно від того, стиснута вона чи немає, тому SQL-запити не доведеться міняти, коли ви вирішите стиснути таблицю. Параметри стиснення таблиці зазвичай встановлюються і змінюються адміністраторами або архітекторами бази даних, і участь в цьому процесі розробників або користувачів мінімально.

Як створити стиснуту таблицю


Для створення стислій таблиці використовується ключове слово COMPRESS в операторі CREATE TABLE. Ключове слово COMPRESS вимагає від сервера Oracle, по можливості, зберігати рядки таблиці в стислому вигляді. Нижче представлений приклад оператора CREATE
TABLE COMPRESS:

CREATE TABLE SALES_HISTORY_COMP (
PART_ID VARCHAR2(50) NOT NULL,
STORE_ID VARCHAR2(50) NOT NULL,
SALE_DATE DATE NOT NULL,
QUANTITY NUMBER(10,2) NOT NULL
)
COMPRESS;

Можна також використовувати оператор ALTER TABLE для зміни атрибута стиснення існуючої таблиці, як в наступному прикладі:

ALTER TABLE SALES_HISTORY_COMP COMPRESS;

Щоб дізнатися, чи використовувалася ключове слово COMPRESS у визначенні таблиці, виконайте запит до подання USER_TABLES словника даних і перевірте значення стовпця COMPRESSION, як у наступному прикладі:

SELECT TABLE_NAME, COMPRESSION FROM USER_TABLES;
TABLE_NAME COMPRESSION
—————— ———–
SALES_HISTORY DISABLED
SALES_HISTORY_COMP ENABLED

Атрибут COMPRESS також може бути заданий на рівні табличного простору, як в момент його створення (за допомогою оператора CREATE TABLESPACE), так і в Надалі (за допомогою оператора ALTER TABLESPACE). Атрибут COMPRESS успадковується аналогічно параметрам зберігання. При створенні таблиці в табличному просторі успадковується атрибут COMPRESS цього табличного простору. Щоб визначити, заданий чи для табличного простору атрибут COMPRESS, виконайте запит до поданням DBA_TABLESPACES словника даних і перевірте значення стовпця DEF_TAB_COMPRESSION, як у наступному прикладі:

SELECT TABLESPACE_NAME,
DEF_TAB_COMPRESSION
FROM DBA_TABLESPACES;
TABLESPACE_NAME DEF_TAB_COMPRESSION
————— ——————-
DATA_TS_01 DISABLED
INDEX_TS_01 DISABLED

Як і слід було очікувати, ви можете стискати або не стискати таблицю в табличному просторі, незалежно від значення COMPRESS, заданого на рівні табличного простору.

Завантаження даних в стислу таблицю


Врахуйте, що при вказівці ключового слова COMPRESS, як показано в прикладах вище, ви, фактично, ніяких даних не стискаєте. Представлені вище команди змінюють тільки установку в словнику даних. Дані реально не стискуються, поки не будуть завантажені або вставлені в таблицю.

Більш того, щоб гарантувати фактичне стиснення даних, треба використовувати відповідний метод завантаження або вставки даних в таблицю. Стиснення даних відбувається тільки при масовій завантаженні або в процесі масової вставки, з допомогою одного з наступних чотирьох методів:


Метод безпосереднього завантаження SQL * Loader – найбільш зручний спосіб завантаження даних в таблицю, якщо дані доступні в текстовому файлі. Приклад представлений нижче:

$sqlldr sanjay/sanjay@proddb control=sales_history.ctl direct=true

Якщо дані доступні в проміжній (staging) таблиці, можна використовувати послідовні оператори INSERT з підказкою APPEND або паралельний INSERT.

Як приклад розглянемо випадок, коли вхідні дані доступні в не стислій проміжної таблиці SALES_HISTORY. Використовуючи метод послідовної вставки, можна використовувати наступний оператор для вставки даних в стислу таблицю:

INSERT /*+ APPEND */
INTO SALES_HISTORY_COMP
SELECT * FROM SALES_HISTORY;

Для перенесення даних з проміжної таблиці в стислу можна також використовувати паралельний INSERT, як показано нижче:

ALTER SESSION ENABLE PARALLEL DML;
INSERT /*+PARALLEL(SALES_HISTORY_COMP,4)*/
INTO SALES_HISTORY_COMP
SELECT * FROM SALES_HISTORY;

Врахуйте, що при використанні паралельного INSERT треба спочатку включити розпаралелювання операторів DML в сеансі за допомогою команди ALTER SESSION ENABLE
PARALLEL DML.

Якщо вхідні дані представлені в звичайному файлі, можна також звернутися до нього як до зовнішньої таблиці, а потім вставляти дані в стислу таблицю так само, як з проміжної таблиці. (Обговорення зовнішніх таблиць виходить за рамки цієї статті.)

Можна також використовувати оператор CREATE TABLE … AS SELECT для створення стислій таблиці і вставки в неї даних за один крок. Ось приклад:

CREATE TABLE SALES_HISTORY_COMP
COMPRESS
AS SELECT * FROM SALES_HISTORY;

Якщо не використовувати відповідний метод завантаження або вставки даних, дані в таблиці виявляться не стисненими, хоча для таблиці і визначено атрибут COMPRESS. Наприклад, якщо використовувати звичайну завантаження (conventional path) з допомогою SQL * Loader або звичайні оператори INSERT, дані не будуть стискуватися.

Коли використовувати стиснення таблиць


Вживаний сервером Oracle алгоритм прийняття рішення про те, стискати дані таблиці або не стискати, призводить до певних висновків про особливості додатків, найбільше підходять для стиснення таблиць. Як було описано вище, дані в таблиці з атрибутом COMPRESS стискаються тільки при безпосередній завантаженні або при вставці з використанням підказки append і розпаралелюванням. Дані, вставлені звичайними операторами INSERT, залишаться не стислими.

В системах оперативної обробки транзакцій (online transaction processing – OLTP) дані зазвичай вставляються звичайними операторами INSERT. В результаті, від використання стиснення для відповідних таблиць великої переваги не буде. Стиснення таблиць найбільше підходить для таблиць тільки для читання, дані в які завантажуються один раз, а читаються – багаторазово. Таблиці, що використовуються при організації сховищ даних, наприклад, прекрасно підходять для стиснення.

Більше того, зміна даних в стислій таблиці може зажадати розпакування рядків, що зводить нанівець всі переваги стиснення. В результаті, часто змінювані таблиці погано підходять для стиснення.

Нарешті, треба врахувати наслідки видалення рядка при використанні стиснення таблиці. При видаленні рядка в стислій таблиці сервер звільняє місце, займане рядком у блоці. Це вільне місце може бути повторно використано при будь-якого подальшого вставці. Однак оскільки рядок, вставлена ​​в звичайному режимі, не стискається, малоймовірно, що вона поміститься в звільнилося від стислій рядка місце. Значна кількість послідовно виконуваних операторів DELETE і INSERT може викликати фрагментацію і дискового простору при цьому буде марно використовуватися більше, ніж вдалося заощадити за рахунок стиснення.

Стиснення існуючої не стислій таблиці


Вже існуючі не стислу таблицю можна стиснути за допомогою оператора ALTER TABLE … MOVE. Наприклад, не стиснуту таблицю SALES_HISTORY_TEMP можна стиснути з допомогою наступного оператора:

ALTER TABLE SALES_HISTORY_TEMP
MOVE COMPRESS;

Оператор ALTER TABLE … MOVE можна використовувати і для скасування стиснення таблиці, як у наступному прикладі:

ALTER TABLE SALES_HISTORY_TEMP
MOVE NOCOMPRESS;

Врахуйте, що оператор ALTER TABLE … MOVE встановлює Монопольне блокування таблиці, що запобігає виконання будь-яких операторів DML з таблицею на час виконання цього оператора. Цією потенційної проблеми можна уникнути за рахунок використання оперативного перевизначення таблиці (online table redefinition), що з’явився в Oracle9i.

Стиснення матеріалізованого подання


Матеріалізовані уявлення можна стискати точно так само, як і таблиці. Наступний оператор створює стислий матеріалізоване уявлення:

CREATE MATERIALIZED VIEW MV_SALES_COMP COMPRESS AS SELECT P.PART_NAME, H.STORE_ID,
H.SALE_DATE, H.QUANTITY FROM SALES_HISTORY H, PARTS P WHERE P.PART_ID = H.PART_ID;

Матеріалізовані уявлення на основі сполук декількох таблиць зазвичай добре піддаються стисненню, оскільки в них часто зустрічаються повторювані компоненти даних. Атрибут стиснення для матеріалізованого уявлення можна змінити за допомогою оператора ALTER MATERIALIZED VIEW. Наступний оператор показує, як стиснути існуюче не стислий матеріалізоване уявлення:

ALTER MATERIALIZED VIEW MV_SALES COMPRESS;

При використанні цього оператора врахуйте, що стиснення фактично відбудеться при наступному оновленні матеріалізованого уявлення.

Стиснення секціонірованние табліци1


Варіантів використання стиснення для секціонованих таблиць багато. Стиснення можна застосовувати або на рівні таблиці, або на рівні секції. Наприклад, оператор CREATE TABLE в лістингу 1 створює таблицю з чотирьох секцій. Оскільки COMPRESS задається на рівні таблиці, всі чотири секції будуть стискатися.

Оскільки стиск може бути задано на рівні секції, можна деякі секції стиснути, а інші залишити не стислими. Приклад в Лістингу 2 демонструє, як задати стиснення на рівні секції.

В Лістингу 2 дві секції таблиці (SALES_Q1_03 і SALES_Q2_03) стислі, а інші дві залишаються не стислими. Врахуйте, що атрибути стиснення, задані на рівні секції, перевизначають атрибути, задані для цієї ж секції на рівні таблиці. Якщо атрибут стиснення для секції не заданий, ця секція успадковує значення з визначення на рівні таблиці. В Лістингу 2, оскільки атрибути стиснення для секцій SALES_Q3_03 і SALES_Q4_03 не вказані, ці дві секції успадковують значення з визначення таблиці (яке, в даному випадку, стандартно – NOCOMPRESS).

Секціонірованние таблиці забезпечують спільно зі стисненням одне унікальне перевагу. Один з корисних способів секціонірована таблиці – помістити підлягають зміні (вставці, оновлення та видалення) дані в окремі секції, а дані тільки для читання винести в інші. Наприклад, у визначенні таблиці в Лістингу 2 дані про продажі секціонірована за значенням стовпця SALE_DATE, так що хронологічна інформація про продажі в кожному кварталі зберігається в окремій секції. У цьому прикладі дані про продажі за перший (Q1) і другий (Q2) квартали 2003 року не можуть бути змінені, тому вони поміщені в стислі секції SALES_Q1_03 і SALES_Q2_03. Дані про продажі за третій (Q3) і четвертий (Q4) квартали все ще можуть змінюватися, тому відповідні секції, SALES_Q3_03 і SALES_Q4_03, залишені не стислими.

Якщо в кінці третього кварталу 2003 року дані в секції SALES_Q3_03 стають доступними тільки для читання, можна стиснути цю секцію за допомогою оператора ALTER TABLE … MOVE PARTITION, як показано нижче:

ALTER TABLE SALES_PART_COMP
MOVE PARTITION SALES_Q3_03 COMPRESS;

Щоб дізнатися, які секції таблиці стислі, можна виконати запит до поданням USER_TAB_PARTITIONS словника даних, як у наступному прикладі:

SELECT TABLE_NAME, PARTITION_NAME,
COMPRESSION
FROM USER_TAB_PARTITIONS;
TABLE_NAME PARTITION_NAME COMPRESSION
—————————- ———–
SALES_PART_COMP SALES_Q4_03 DISABLED
SALES_PART_COMP SALES_Q1_03 ENABLED
SALES_PART_COMP SALES_Q2_03 ENABLED
SALES_PART_COMP SALES_Q3_03 ENABLED

Оцінка переваг


Основною причиною використання стиснення таблиці є економія дискового простору. Таблиця в стислому вигляді зазвичай займає менше місця. Щоб проілюструвати це твердження, розглянемо наступний з двома таблицями: одна не стислий (SALES_HISTORY), а інша – стисла (SALES_HISTORY_COMP). В обидві ці таблиці дані були завантажені за допомогою безпосереднього завантаження утилітою SQL * Loader з текстового файлу, що містить два мільйона рядків. Після виконання обох завантажень виявилося, що стисла таблиця займає на диску майже вдвічі менше місця, ніж не стисла. Аналіз представлений в Лістингу 3.

Той факт, що для зберігання стислій таблиці треба менше блоків, призводить до економії дискового простору, але зменшення кількості блоків може призводити і до підвищення продуктивності. Запити до стислій таблиці в середовищі з обмеженою продуктивністю вводу-виводу часто будуть виконуватися швидше, оскільки вимагають прочитання меншої кількості блоків. Щоб проілюструвати це твердження, я виконав запит до стислій і не стислій таблиці і проаналізував результати SQLTRACE / TKPROF. Ці результати представлені в Лістингу 4.

Звіт SQLTRACE / TKPROF показує, що мій запит до стислій таблиці зажадав менше операцій фізичного та логічного введення-виведення, ніж аналогічний запит до НЕ стислій таблиці, і, як наслідок, виконується швидше.

Зниження продуктивності при завантаженні


Оскільки стиск таблиці виконується при масовій завантаженні, операції завантаження вимагають додаткової обробки – треба виконувати додаткові дії. Щоб виміряти вплив стиснення на продуктивність, я виконав тест, в якому завантажував один мільйон рядків (за допомогою безпосереднього завантаження утилітою SQL * Loader) у дві ідентичних таблиці: зі стисненням і без стиснення. У Таблиці 1 представлені результати, взяті з журнальних файлів SQL * Loader і показують, скільки часу знадобилося для завантаження даних в кожну з таблиць.





















Ім’я таблиці Кількість рядків Спосіб завантаження Стисла? Час завантаження
SALES_HISTORY 1000000 Безпосередня Чи не стисла 00:00:21.12
SALES_HISTORY_COMP 1000000 Безпосередня Стисла 00:00:47.77

Таблиця 1: Порівняння часу завантаження даних для стислій і не стислій таблиць

Додатковий час при завантаженні в стислу таблицю потрібно для виконання дій зі стиснення даних при завантаженні. В реальній ситуації відмінність у часі завантаження буде залежати від особливостей таблиці і завантажуваних даних.

Висновок


Стиснення таблиці в Oracle9i Release 2 дозволяє істотно заощадити дисковий простір, особливо в базах даних, що містять великі таблиці тільки для читання. Якщо враховувати додаткові вимоги до завантаження і вставці даних, а також правильно вибрати таблиці-кандидати для стиснення, стиск таблиць може виявитися приголомшливим способом економії дискового простору і, в деяких випадках, підвищення продуктивності запитів.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*