Oracle дата создания таблицы
Могу ли я узнать, когда последний оператор INSERT, UPDATE или DELETE был выполнен для таблицы в базе данных Oracle, и если да, то как?
Немного предыстории: версия Oracle - 10g. У меня есть пакетное приложение, которое запускается регулярно, считывает данные из одной таблицы Oracle и записывает их в файл. Я хотел бы пропустить это, если данные не изменились с момента последнего выполнения задания.
Приложение написано на C ++ и взаимодействует с Oracle через OCI. Он входит в Oracle с «обычным» пользователем, поэтому я не могу использовать какие-либо специальные функции администратора.
Изменить: Хорошо, «Особые административные вещи» не совсем хорошее описание. Я имею в виду: я не могу ничего делать, кроме ВЫБОРА из таблиц и вызова хранимых процедур. К сожалению, изменение чего-либо в самой базе данных (например, добавление триггеров) не является вариантом, если вы хотите сделать это до 2010 года.
Да . комментарий 2010 года касается медлительности ваших администраторов баз данных, насколько я понимаю?
Ну вроде как. Они медленные, но, как я сказал в предыдущем комментарии, я их понимаю. Если есть проблема с этой базой данных, она становится очень уродливой, очень быстро. Вы можете получить туда материал, но только после того, как его проанализирует кучка людей.
Я действительно опоздал на эту вечеринку, но вот как я это сделал:
Это достаточно близко для моих целей.
Поскольку вы используете 10g, вы потенциально можете использовать ORA_ROWSCN псевдоколонку. Это дает вам верхнюю границу последнего SCN (номера изменения системы), вызвавшего изменение в строке. Поскольку это возрастающая последовательность, вы можете сохранить максимум, ORA_ROWSCN который вы видели, а затем искать только данные с SCN больше этого.
По умолчанию ORA_ROWSCN фактически поддерживается на уровне блока, поэтому изменение любой строки в блоке изменит значение ORA_ROWSCN для всех строк в блоке. Этого, вероятно, вполне достаточно, если намерение состоит в том, чтобы минимизировать количество строк, которые вы обрабатываете несколько раз без изменений, если мы говорим о «обычных» шаблонах доступа к данным. Вы можете перестроить таблицу, ROWDEPENDENCIES что приведет ORA_ROWSCN к отслеживанию на уровне строк, что даст вам более детальную информацию, но потребует одноразовых усилий для перестроения таблицы.
Другой вариант - настроить что-то вроде Change Data Capture (CDC) и сделать ваше приложение OCI подписчиком на изменения в таблице, но это также требует одноразовых усилий для настройки CDC.
Ого, это действительно круто. Я пропустил эту псевдоколонку. но я бы не стал использовать CDC . слишком сложный для его целей. Я бы использовал DCN (уведомление об изменении базы данных).
Спросите своего администратора базы данных об аудите. Он может начать аудит с помощью простой команды, например:
Затем вы можете запросить таблицу USER_AUDIT_OBJECT, чтобы определить, была ли вставка в вашу таблицу с момента последнего экспорта.
Google для аудита Oracle для получения дополнительной информации .
Спасибо. Я предполагаю, что именно так и должно быть сделано. К сожалению, «спросить администратора базы данных», как правило, довольно сложно. Они действительно параноики насчет того, чтобы что-то менять. Я их понимаю. Если с этой базой данных что-то не так, все становится некрасиво.
Мне нужна таблица MySQL для хранения всех дат между 2011-01-01 и 2011-12-31. Я создал таблицу с именами столбцов "_date", введите DATE.
с помощью какого запроса я могу заполнить таблицу всеми желаемыми датами (вместо того, чтобы вводить их вручную)?
EDIT (чтобы проверить, существует ли дата), как задано Эндрю Фокс.
это просто оптимизировать и масштабировать эту таблицу для других целей. Вы можете легко избавиться от десятков и сотни таблиц, если вам нужна только одна неделя данных.
Если вам нужен больший набор чисел, легко добавить таблицу тысяч. Вам нужно только скопировать и вставить таблицу с сотнями и добавить ноль до 9 чисел.
Я нашел эту пасту-и-го варианта работы:
Если у вас есть таблица с достаточно большим смежным набором идентификаторов, вы можете использовать -
примечание: но имейте в виду, что это может привести вас в беду во время високосных лет (имея 366 дней)
Если вы находитесь в ситуации, как и я, где процедуры запрещены, и ваш пользователь sql не имеет разрешений для вставки, поэтому "вставить" не допускается, а вы хотите создать список дат в конкретный период, скажем, в текущем году, чтобы сделать некоторую агрегацию, используйте это
спасибо Иванду. У меня есть лучшее решение, которое позволяет вам создать указанную таблицу календаря. Например, если я пытаюсь создать таблицу 2014-04, это выглядит так:
Это может быть достигнуто в PHP с помощью простого цикла for. Есть несколько способов сделать это. Один из способов-поместить исходную дату в переменную и запустить цикл через нее для каждого дня, добавив +1 день в каждом цикле, например, вы начнете с 01/01/2011, а затем цикл добавит 0 в первый раз, 1 день на следующий, затем 2 дня и так далее к переменной $i. Затем вы можете распечатать дни или добавить их в свою базу данных. В этом случае $я бы представьте счетчик с 0 в качестве начальной точки,
date ('Y-m-d' преобразует дату в гггг-ММ-ДД. Использование заглавной буквы Y дает вам полный 4-значный год, тогда как использование нижнего регистра y даст вам последние 2 цифры года. Вы хотите сохранить его в этом порядке, чтобы добавить его в поле даты в для MySQL.
strtotime ($originalDate анализирует дату в метку времени Unix и ."+ " .$i. "день") в основном добавляет значение $i в днях к дате.
наконец, есть запрос mysqli. $db представляет переменную подключения к базе данных, ее необходимо изменить на любую переменную, заданную для подключения. За этим следует фактический запрос. Просто замените таблицу word на имя таблицы и дату перед значениями, чтобы вы датировали имя строки, и вы готовы ходить.
другой способ достичь этого с помощью функции for - это включить даты strtotime непосредственно в действия for как противоположность переменным счетчика, что является еще более коротким фрагментом кода. Замените $i=0 (начальная точка счетчика) на начальную точку дня, выполните это с точкой меньше или равной точке конца дня (количество циклов) , а затем, наконец, с вашим плюсом +1 до первого оператора, помещенного в переменная готова к использованию.
наконец, преобразуйте дату в формат Y-m-d, готовый для размещения в базе данных, и запустите запрос.
опять же, как и в первом примере, это можно распечатать или поместить непосредственно в вашу базу данных.
Я, вероятно, сделал это более запутанным, чем это есть, но надеюсь, что это, по крайней мере, даст вам представление о том, как это работает.
недавно мне нужно было создать calendar_date таблица, как показано ниже:
затем я заселил его всеми возможными датами между January 1, 2001 и December 31, 2100 (оба включительно) используя запрос ниже:
в моей локальной базе данных MySQL, INSERT запрос занял всего несколько секунд. Надеюсь, это кому-то поможет.
вдохновленный большим количеством Иванда присоединиться я прихожу к этому:
Могу ли я узнать, когда последний оператор INSERT, UPDATE или DELETE был выполнен для таблицы в базе данных Oracle, и если да, то как?
Немного предыстории: версия Oracle - 10g. У меня есть пакетное приложение, которое запускается регулярно, считывает данные из одной таблицы Oracle и записывает их в файл. Я хотел бы пропустить это, если данные не изменились с момента последнего выполнения задания.
Приложение написано на C ++ и взаимодействует с Oracle через OCI. Он входит в Oracle с «обычным» пользователем, поэтому я не могу использовать какие-либо специальные функции администратора.
Изменить: Хорошо, «Особые административные вещи» не совсем хорошее описание. Я имею в виду: я не могу ничего делать, кроме ВЫБОРА из таблиц и вызова хранимых процедур. К сожалению, изменение чего-либо в самой базе данных (например, добавление триггеров) не является вариантом, если вы хотите сделать это до 2010 года.
Да . комментарий 2010 года касается медлительности ваших администраторов баз данных, насколько я понимаю?
Ну вроде как. Они медленные, но, как я сказал в предыдущем комментарии, я их понимаю. Если есть проблема с этой базой данных, она становится очень уродливой, очень быстро. Вы можете получить туда материал, но только после того, как его проанализирует кучка людей.
Поскольку вы используете 10g, вы потенциально можете использовать псевдостолбец ORA_ROWSCN . Это дает вам верхнюю границу последнего SCN (номера изменения системы), вызвавшего изменение в строке. Поскольку это возрастающая последовательность, вы можете сохранить максимальное значение ORA_ROWSCN , которое вы видели, а затем искать только данные с более высоким SCN.
По умолчанию ORA_ROWSCN фактически поддерживается на уровне блока, поэтому изменение любой строки в блоке изменит ORA_ROWSCN для всех строк в блоке. Этого, вероятно, вполне достаточно, если намерение состоит в том, чтобы минимизировать количество строк, которые вы обрабатываете несколько раз без изменений, если мы говорим о «обычных» шаблонах доступа к данным. Вы можете перестроить таблицу с помощью ROWDEPENDENCIES , что приведет к отслеживанию ORA_ROWSCN на уровне строки, что дает вам более детальную информацию, но требует единовременных усилий для восстановления таблицы.
Другой вариант - настроить что-то вроде Change Data Capture (CDC) и сделать ваше приложение OCI подписчиком на изменения в таблице, но это также требует одноразовых усилий для настройки CDC.
Ого, это действительно круто. Я пропустил эту псевдоколонку. но я бы не стал использовать CDC . слишком сложный для его целей. Я бы использовал DCN (уведомление об изменении базы данных).
Создание таблицы
Приветствую. Помогите пожалуйста с кодом для создания таблицы БД Oracle 11g. Как это будет.
Создание таблицы с автоинкрементом
Добрый вечер. Знаю, вопрос глупый, но уже не знаю какой час сижу. Я написал следующий код.
Создание таблицы в Oracle
Только начал изучать Oracle. Посоветуйте пожалуйста хороший пример создания таблицы пошагово. Для.
Создание таблицы с идентефикатором ID
Всем добрый день. Подскажите пожалуйста как при создании таблицы SQL через С++ builder, сделать так.
Добавлено через 1 час 31 минуту
во второй строчке выдает ошибку - неверный символ,только не могу понять что там неверного
Добавлено через 21 минуту
нашла во второй строке ошибку,теперь выдает в 6
Добавлено через 8 минут
пишет неверный тип данных,что-то не могу разобраться,что именно неправильно,подскажите пожалуйста!
Добавлено через 16 минут
вот переделала,получилось
Насчет формата не подскажу, а вот о создании таблиц.
в заданиии сказано "Создать последовательности для генерации номеров книг и читателей"
спасибо,совсем забыла про генерацию
Добавлено через 36 минут
вот правда я запуталась в третьей таблице с датами
объясните,плиз,как создать дату,сделать её текущей,и ту,что позже
никак не могу разобраться,уже запуталась совсем
а вот допустим у меня идет дата вторая позже чем первая,но не написано на сколько позже,то как это записать?
вот условие Создать таблицу,и в ней идут столбцы № читателя,№ книги,дата выдачи (текущая дата),дата возврата(должна быть позже чем дата выдачи)
Добавлено через 3 минуты
вот что я пока написала
текущая дата - SYSDATE
книга выдается, к примеру, на 14 дней - SYSDATE+14
в инсерте пишешь для этих полей
скажитк пожалуйста поле Id или нет
просто когда я в таблице
создаю форму на апексе у мея поле с pk не появляеться
и я не могу ввести номер паспаспорта
а если я делаю вот так
и вот так еще
create sequence _seq
increment by 1 // увеличение на единицу
start with 40 // начинаем с сорокового номера
то форма прекрасно работает
вопрос можно ли что нбудь сделать с первым случаем или лучше работать по второму
а объеденение таблиц делать по принцепу select list, radio group, check box
foreign key также дать id
Создание истории изменения таблицы
Доброго времени суток Требуется сохранять изменения одной таблицы в другой таблице. То есть.
Создание temp таблицы из существующей
Добрый день. Требуется создать TEMP таблицу и перелить данные из существующей. (для изменения в.
Создание таблицы из файла Excel
Друзья, добрый день. Подскажите, пожалуйста, как создать таблицу используя данные файла Excel?
Скрипт создание таблицы, заполнение данных, запрос
Здравствуйте. Пожалуйста, поделитесь информацией. Я ничего не понимаю, необходимую литературу на.
Создание сквозного счетчика через все таблицы
необходимо создание счетчика решил использовать такую конструкцию CREATE SEQUENCE имя ;.
В этой части статьи рассматриваются особенности создания секционированных таблиц, в следующей речь пойдет об особенностях перевода существующих больших несекционированчых таблиц в секционированные таблицы, а также особенности секционирования индексов и работа с секциями.
Методы секционирования таблиц
Секционирование повышает эффективность работы с таблицами и индексами
Выбранный ключ секционирования, как правило, определяет методы секционирования. В настоящее время имеются следующие методы секционирования таблиц:
- Range -секционирование по диапазону ключа,
- List - секционирование по списку ключа.
- Hash - хеш-секционирование,
- составное секционирование.
- интервальное секционирование.
- ссылочное секционирование,
- системное секционирование
Последние три появились в Oracle 11g. вместе с тем последние два у нас пока не нашли большого применения.
Создание новой секции в секционированной таблице по методу Range
Каждый раз при создании секционированной таблицы возникает непростой вопрос: как создавать новые секции. До Oracle 11g было три варианта создания новой секции.
Первый вариант - это в команде create таблицы вручную создается множество секций (например, на несколько лет вперед). Однако, как показала практика, этот метод приводит к тому, что через несколько лет о том, что таблица была секционирована, могут забыть. Когда об этом вспоминают, то оказывается, что информация длительное время пишется в одну и ту же последнюю секцию THAN (MAXVALUE) . В результате секционированная таблица практически превратилась в обычную таблицу. В этой ситуации надо либо снова создавать новую секционированную таблицу, либо по команде Split разбивают последнюю секцию на несколько секций. Например, для таблицы AIF.HISTLG (секционированной по дате) команда Split по созданию новой секции PARTMM_2016_01 на основе расщепления последней PARTMM.MAX секции имеет вид:
Фраза UPDATE GLOBAL INDEXES обеспечивает исправность индексов после команды Split.
Второй вариант - создать процедуру, которая автоматически образует новую секцию. Такая универсальная процедура для секционирования по дням и месяцам была нами разработана. Данная процедура запускается Job Sheduler ежедневно для секционирования по дням или ежемесячно для секционирования по месяцам.
Данные процедуры успешно работают уже несколько лет, своевременно создавая новые секции. Основой процедуры являются представление ALL_TAB_PARTITIONS ДЛЯ поиска последней секции таблицы и команда Split для расщепления этой секции по команде ALTER , указанной выше.
Третий вариант (разработан нашими специалистами и успешно применяется в течение несколько лет) - это создание секционированной таблицы с секциями, используемыми по циклу. Под секционированием таблиц по циклу понимаются секционирование, выполненное в соответствии с двумя правилами. Первое правило - таблица должна содержать фиксированное количество секций, равное либо максимальному числу дней в месяце (31 секция), либо максимальному число дней в году (366 секций), либо числу месяцев в году (12 секций). Второе правило: данные в одну и ту же секцию попадают с определенной периодичностью (цикличностью).
Например, в следующем году информация за январь пишется снова в ту же секцию января, что и в прошедшем году. При этом секции чистятся от прошлогодней информации. Преимущество этого метода в том, что не надо создавать новые секции.
В Oracle 11g появилась новая замечательная возможность автоматического создания секций с использованием при создании таблицы фразы INTERVAL (такой подход называется интервальное секционирование Interval Partitioning). Тогда при создании секций методом Range по интервалу дат с использованием фразы Interval команда создания секционированной таблицы примет вид:
где фраза INTERVAL (INTERVAL '1' MONTH) указывает, что секции будут автоматически создаваться каждый месяц (та же фраза может иметь вид INTERVAL (NUMTOYMINTERVAL (1. 'MONTH') . Для секционирования по дням используется фраза INTERVAL (INTERVAL '1' DAY) , а по годам - INTERVAL (INTERVAL '1' YEAR) . При автоматическом создании секций методом Range по интервалу значений с использованием фразы Interval команда создания таблицы примет вид:
где фраза INTERVAL(1000) задает режим автоматического создания секции через 1000 значений ISN.
Следует учесть, что новые секции создаются в процессе ввода данных. Следует также иметь в виду, что имя новой автоматически создаваемой секции будет иметь вид SYS_PNNNNN, например, SYS_P28981. При этом при интервальном секционировании не нужно создавать последнюю секцию VALUES LESS THAN (MAXVALUE) . иначе появится ошибка ORA-14761.
Таким образом, в Oracle 11g у команды create создания секционированной таблицы существенно меньшее число строк, а о создании новой секции своевременно позаботится Oracle.
Составное секционирование
При составном секционировании внутри секции создаются подсекции Однако в версиях до Oracle 11g смешанное секционирование разрешалось только по RANGE методу для секции и методам HASH или LIST для подсекции. В Oracle 11g варианты методов секций-подсекций были существенно расширены, и в настоящее время можно осуществлять составное секционирование в следующих комбинациях: Range-Range, Range-Hash , Range-List, List-Range, List-Hash или Ust-List. Надо отметить, что при составном секционировании данные физически хранятся в подсекциях, а секции высту-пают только в роли логических контейнеров.
Рассмотрим смешанное секционирование на примере таблицы платежей AIF.PAY_ORD_RECORD с делением таблицы на секции по методу RANGE , а на подсекции по методу LIST . Ключом секционирования по секциям выступает столбец PAY_DATA (тип date), а ключом секционирования подсекции выступает столбец STATUS (тип number), принимающий три значения: 0. 1,2. Команда создания секционированной таблицы в Oracle 11g с секционированием по месяцам примет вид:
где разбиение по секциям задает фраза PARTITION BY RANGE (PAY_DATA) , а по подсекциям фраза SUBPARTITION BY LIST (STATUS) . Далее идет список подсекций со своими значениями: STATUS_0 VALUES (0) . STATUSJ VALUES (1) . STATUSJ? VALUES (2) . Для каждой подсекции может быть задано свое табличное пространства, которое может отличаться от табличного пространства таблицы HSTDATA. С гомощью предложения SUBPARTITION TEMPLATE один и тот же набор подсекций будет автоматически использоваться во всех секциях. Однако создание подсекций можно сделать вручную, указав все подсекции для каждого секции. Просмотреть созданные подсекции по имени таблицы можно по запросу:
Ключ секционирования
Следующим важным шагом в создании секционированной таблицы является определение ключа секционирования. В качестве ключа секционирования может выступить столбец или несколько столбцов, относительно значений которых будет делаться разнесение таблицы на секции. К потенциальным столбцам для создания ключа секционирования относятся столбцы типа date (например, столбец created - дата создания строки или updated - дата изменения строки) для секционирования по методам Range и List . Столбцы типа number с высокой степенью уникальности значений хорошо подходят для секционирования по методам Range и Hash . Столбцы, имеющие список фиксированных значений, подходят для секционирования по списку List .
В Oracle 11g появилась возможность в качестве ключа секционирования использовать виртуальный столбец (virtual column), построенный на функции к реальному столбцу таблицы. Виртуальный столбец в действительности не хранится в таблице, а каждый раз вычисляется при обращении к нему во время ввода данных в таблицу. Для создания виртуального столбца используется фраза generated always as. после которой идет функция, выполняемая над реальным столбцом таблицы, а далее идет обязательная фраза virtual. Например, PARTID generated always AS (to_char(UPDATED,'MM')) virtual . Возможен вариант создания виртуального столбца более короткой фразой PARTID AS (to_char(UPDATED,'MM')) .
Увидеть, какой столбец в таблице виртуальный позволяет запрос:
Замечание. При вводе данных в таблицу с виртуальным столбцом следует указать в insert и values перечень столбцов, иначе будет ошибка ORA-00947: not enough value .
Секционирование методом Range по диапазону дат
При секционировании этим методом нами используются секционирование по дням, месяцам и по годам. Секционирование этим методом покажем на примере таблицы HISTLG в схеме AIF. Ключом секционирования выступает столбец updated (дата корректировки строки), при этом секции создаются с шагом секций в один месяц. Команда создания секционированной таблицы create имеет вид:
В команде CREATE указаны табличное пространство TABLESPACE HSTDATA, в котором будет находиться таблица, метод секционирования и ключ секционирования PARTITION BY RANGE (UPDATED) , имена секций и максимальное значение диапазона ключевого столбца этой секции. Например, первая секция PARTITION PARTMM_2015_01 VALUES LESS THAN TO_DATE('01.01.20157DD.MM.YYYY') говорит о том, что все значения столбца update меньше 01.01.2015 попадут в первую секцию, а значения update меньше 01.02.2015 попадут во вторую секцию и т.д. В таблице создана последняя секция PARTITION PARTMM_MAX VALUES LESS THAN (MAXVALUE) , позволяющая при превышении значения ключа значения диапазона предпоследней секции размещать строки таблицы в эту последнюю секцию (это подстраховка на случай, если забыли создать новую секцию). Фраза COMPRESS определяет, что первая секция будет сжата.
Следует обратить особое внимание на последнюю фразу ENABLE ROW MOVEMENT , которая позволяет переходить строкам таблицы из секции в секцию. В отсутствии этой фразы Oracle выдаст ошибку. Переход строк по секциям может происходить автоматически при изменении значения ключа (например, столбец updated в результате операции update изменит значение на то. при котором он должен уже принадлежать другой секции) или может происходить специально, например, для перевода строк из оперативной секции в архивную секцию путем изменения значения ключевого столбца. Если не указали эту фразу при создании таблицы, то, чтобы избежать ошибки, следует выполнить команду ALTER TABLE ИМЯ ТАБЛИЦЫ ENABLE ROW MOVEMENT .
Увидеть секции таблицы можно по запросу:
А содержимое секции по запросу:
Задачи, решаемые секционированием
Прежде чем приступить к секционированию, надо четко определить задачи, которые предполагается решить
- Первой и наиболее часто решаемой задачей при секционировании является повышение производительности работы SQL-запросов и DML-операций по модификации строк таблицы. Это достигается за счет того, что поиск и модификация строк в таблице идут не по всей таблице, а только в ее части (в одной или нескольких секциях). Кроме того, разбиение таблицы на секции позволяет увеличит скорость обработки таблицы за счет использования параллелизма.
- Вторая задача, которая нашла широкое применение в нашей организации, - это быстрое удаление значительного числа строк в больших таблицах за счет выполнения операции truncate секций. Другим широким применением секционирования является освобождение табличного пространства, занимаемого таблицей, после удаления строк из таблицы командой delete. Использование команд Shrink (сжатие таблицы) или Move (перемещение в табличное пространство) для освобождения табличного пространства в большой несекционированной таблице может занимать значительное время. В секционированных таблицах выполнение таких команд в пределах секции будет выполниться существенно быстрее.
- Третьей задачей секционирования является разбиение большой таблицы на оперативную и архивную части. Особенно это эффективно, если оперативная часть в виде секции интенсивно пополняется и модифицируется, а архивная часть (секции) менее подвержена изменениям, и существенно реже из нее извлекается информация. Строки таблицы из оперативной секции со временем могут быть переведены в архивные секции, при этом архивные секции могут периодически очищаться.
- Четвертой задачей является существенное снижение конкуренции за строки и индексы таблицы, в том числе уменьшения вероятности блокировок. Так в результате секционирования одной из таблиц по HASH-методу полностью была решена задача множественных блокировок, возникающих в таблице.
- Пятой задачей является обеспечение устойчивости функционирования таблиц. Поскольку секция - это поименованный самостоятельный фрагмент памяти на дисках, то при возникновении проблем в одних секциях другие продолжают успешно функционировать. Устойчивости функционирования способствует также хранение секций в различных табличных пространствах и на различных физических носителях. Это особенно важно для таблиц, которые обеспечивают работу множества других таблиц (например. справочники, к которым идет интенсивное обращение). Кроме того, секционирование позволяет осуществлять независимое копирование и резервирование секций, оперативное восстановление секций, а также возможности более быстрой и более частой перестройки индексов наиболее активной секции, не затрагивая индексы пассивных секций.
Секционирование методом RANG по диапазону значений
Секционирование по диапазону значений похоже на секционирование по диапазону дат, только вместо ключа по дате используется ключ по столбцу, принимающему числовое значение (желательно имеющее равномерное распределение по всему диапазону значений). Для этого хорошо подходит столбец с уникальным значением. Рассмотрим на примере той же таблицы AIF.HISTLG, секционированной выше по диапазону дат. В качестве ключа секционирования используется столбец ISN с уникальными значениями. Команда создания таблицы имеет вид:
где PARTITION BY RANGE (ISN) говорит о секционировании no RANGE при ключе секционирования ISN, интервал создания секции через 1000 значений.
Задачи, решаемые секционированием
Прежде чем приступить к секционированию, надо четко определить задачи, которые предполагается решить
- Первой и наиболее часто решаемой задачей при секционировании является повышение производительности работы SQL-запросов и DML-операций по модификации строк таблицы. Это достигается за счет того, что поиск и модификация строк в таблице идут не по всей таблице, а только в ее части (в одной или нескольких секциях). Кроме того, разбиение таблицы на секции позволяет увеличит скорость обработки таблицы за счет использования параллелизма.
- Вторая задача, которая нашла широкое применение в нашей организации, - это быстрое удаление значительного числа строк в больших таблицах за счет выполнения операции truncate секций. Другим широким применением секционирования является освобождение табличного пространства, занимаемого таблицей, после удаления строк из таблицы командой delete. Использование команд Shrink (сжатие таблицы) или Move (перемещение в табличное пространство) для освобождения табличного пространства в большой несекционированной таблице может занимать значительное время. В секционированных таблицах выполнение таких команд в пределах секции будет выполниться существенно быстрее.
- Третьей задачей секционирования является разбиение большой таблицы на оперативную и архивную части. Особенно это эффективно, если оперативная часть в виде секции интенсивно пополняется и модифицируется, а архивная часть (секции) менее подвержена изменениям, и существенно реже из нее извлекается информация. Строки таблицы из оперативной секции со временем могут быть переведены в архивные секции, при этом архивные секции могут периодически очищаться.
- Четвертой задачей является существенное снижение конкуренции за строки и индексы таблицы, в том числе уменьшения вероятности блокировок. Так в результате секционирования одной из таблиц по HASH-методу полностью была решена задача множественных блокировок, возникающих в таблице.
- Пятой задачей является обеспечение устойчивости функционирования таблиц. Поскольку секция - это поименованный самостоятельный фрагмент памяти на дисках, то при возникновении проблем в одних секциях другие продолжают успешно функционировать. Устойчивости функционирования способствует также хранение секций в различных табличных пространствах и на различных физических носителях. Это особенно важно для таблиц, которые обеспечивают работу множества других таблиц (например. справочники, к которым идет интенсивное обращение). Кроме того, секционирование позволяет осуществлять независимое копирование и резервирование секций, оперативное восстановление секций, а также возможности более быстрой и более частой перестройки индексов наиболее активной секции, не затрагивая индексы пассивных секций.
Системное секционирование (system partitioning)
Появилось в Oracle 11 g и применяется, как правило, для таблиц, которые не могут быть секционированы никакими другими методами. В этом методе Oracle сам управляет, какую строку таблицы в какую секцию помещать. Для этого метода необходимо просто написать название секций, например, секции Р1, Р2, РЗ:
Увидеть разбиение таблицы на секции можно по запросу:
Увидеть метод секционирования, что он именно SYSTEM , можно по запросу:
Следует заметить, что для правильного ввода данных в таблицу надо, помимо имени таблицы, указать еще имя сегмента, иначе будет ошибка ORA-14701 . Тоже для ускоренной выборки данных по запросу следует указать имя сегмента.
Замечание. В таблице подвергнуться секционированию может не только сама таблица, но и индексы таблицы. В силу объемности и важности материала о секционировании индексов пойдет речь во второй части. Там же будет рассказано об особенностях перехода от несекционированных больших по объему таблиц к секционированным таблицам, в том числе о возникающих в этих случаях особенностях поведения индексов, триггеров, синонимов и т.д. этих таблиц.
Хеш-секционирование HASH
Как правило, если не получается секционировать по диапазону RANGE или LIST , то применяется хешсекционирование, основанное на хеш-функции. В этом случае строки таблицы равномерно распределяются между секциями на основании внутренних алгоритмов хеширования Oracle. При этом чем уникальнее значения столбца в таблице, по которому идет секционирование, тем лучше будет распределение данных по разделам. Первичный ключ или уникальный столбец (столбцы) является самым хорошим хеш- ключом. Oracle рекомендует число секций N как степень 2, т.е. N=2,4,8,16,32 и т.д. При этом добавление или удаление какой-то хеш-секции вызывает перезапись всех данных в другие секции. Рассмотрим HASH секционирование на примере индексноорганизованной таблицы LISTIN. Целью HASH секционирования таблицы было добиться существенного снижение числа блокировок, возникающих в этой таблице. Эта цель была успешно реализована за счет секционирования таблицы по 16 секциям (фраза PARTITIONS 16 ), где ключом секционирования выступал столбец TASKISN. Команда создания таблицы имеет вид:
Следует заметить, что если в качестве ключа секционирования используется столбец, в котором имеем очень неравномерное распределение значения столбца (малая уникальность), то применение хеш-секционирования не целесообразно. При этом число секций не имеет особого значения, поскольку все значения ключевого столбца «свалятся» в одну-две секции.
Замечание. Увидеть размер секций в mb по всем указанным выше методам можно по запросу:
Секционирование по списку ключей LIST
Секционирование по списку применяется, если есть возможность указать конкретный перечень дискретных значений столбца, по которому происходит разбиение на секции. При секционировании по LIST в команде create указываются метод секционирования LIST (PARTITION BY LIST) , ключ секционирования и имена секций, в которых указывается одно или несколько дискретных значений.
В качестве примера проведем секционирование таблицы AIF.AGREEM. используя в качестве ключа виртуальный столбец partid. При каждом вводе строки в таблицу в виртуальном столбце формируется числовой номер месяца по функции to_number(to_char(updated,'MM')) . Таблицу разбиваем на 12 секций, кроме того, используем подход секционирования по циклу, когда в следующем году строки января вводятся в ту же секцию января, а перед этим секция за январь чистится от старых данных по delete или по truncate. Команда создания секции примет вид:
Вместо виртуального столбца может быть введен реальный столбец partid (тип number) , заполняемый при вводе строки в таблицу. Указанный выше вариант эффективно использовался в таблицах как с 366 секциями, так и с 12 с очисткой последних по truncate, поскольку информация в таблицах хранится меньше года. Достоинство этого подхода в том, что создавать новые секции не приходится, а табличное пространство старых секций ежемесячно быстро освобождается по truncate .
Замечание. Если необходимо очистить табличное пространство секции, то используются либо команды сжатия SHRINK , либо MOVE (перемещения в табличное пространство):
Другие стандартные варианты секционирования по методу LIST изложены в различных источниках.
Секционирование методом Range по диапазону ключа
В практике секционирования по методу Range используем два вида секционирования: по диапазону дат и по диапазону значений.
Читайте также: