В зависимости от вашего определения «миллионов», ежедневное разбиение на разделы может быть слишком детальным и может вызвать проблемы с производительностью при чтении данных.
Каждый раздел физически хранится как таблица и имеет разные накладные расходы - наиболее важно накладные расходы для выделения пространства сегмента. Oracle почти никогда не выделяет точно , сколько места необходимо, всегда есть немного лишнего. Если вы создаете большое количество крошечных разделов, эта «небольшая дополнительная» может быть больше, чем фактические данные.
В моем тестовом примере, приведенном ниже, предполагается, что 5 миллионов строк в год и относительно небольшое значение в каждом из столбцы, ежедневное разбиение использует в десять раз больше пространства сегментов, чем ежемесячное. Это означает, что ежедневное разбиение будет оптимальным для выбора данных за один день, но будет ужасным для выбора данных за несколько дней. А поскольку полное сканирование таблицы / раздела использует многоблочное чтение и в любом случае считывает мегабайты данных за раз, чтение данных за целый месяц в любом случае может быть не намного медленнее, чем чтение данных за день.
Пример схемы
Создайте три таблицы для ежедневного, ежемесячного и без разбиения. Загрузите 5 миллионов строк равномерно в каждый из 365 дней, а затем проверьте размеры сегментов.
- Ежедневное разбиение использует 2920 мегабайт для 365 сегментов.
- Ежемесячное разбиение использует 288 мегабайт для 13 сегментов.
- Без разбиения на 1 сегмент используется 280 мегабайт.
Код:
----------------------------------------
--DAY
----------------------------------------
create table History_day(
hid number(19,0),
type varchar2(255 char),
lastupdated timestamp (6) not null enable,
name varchar2(255 char),
primary key (hid))
partition by range (lastupdated) interval (numtodsinterval(1,'day'))
(partition retailhistory values less than (to_timestamp('12/01/2020','DD/MM/YYYY')));
create sequence history_day_seq;
begin
for i in 1 .. 365 loop
for j in 1 .. 13698 loop
insert into history_day values(history_day_seq.nextval, 'some type value', date '2020-12-01' + i, 'some name value');
end loop;
end loop;
commit;
end;
/
select sum(bytes)/1024/1024 mb, count(*) partition_count from dba_segments where segment_name = 'HISTORY_DAY';
----------------------------------------
--MONTH: 288 megabytes for 13 partitions.
----------------------------------------
create table History_month(
hid number(19,0),
type varchar2(255 char),
lastupdated timestamp (6) not null enable,
name varchar2(255 char),
primary key (hid))
partition by range (lastupdated) interval (numtoyminterval(1,'month'))
(partition retailhistory values less than (to_timestamp('12/01/2020','DD/MM/YYYY')));
create sequence history_month_seq;
begin
for i in 1 .. 365 loop
for j in 1 .. 13698 loop
insert into history_month values(history_month_seq.nextval, 'some type value', date '2020-12-01' + i, 'some name value');
end loop;
end loop;
commit;
end;
/
select sum(bytes)/1024/1024 mb, count(*) partition_count from dba_segments where segment_name = 'HISTORY_MONTH';
----------------------------------------
--NO PARTITIONS
----------------------------------------
create table History(
hid number(19,0),
type varchar2(255 char),
lastupdated timestamp (6) not null enable,
name varchar2(255 char),
primary key (hid));
create sequence history_seq;
begin
for i in 1 .. 365 loop
for j in 1 .. 13698 loop
insert into history values(history_seq.nextval, 'some type value', date '2020-12-01' + i, 'some name value');
end loop;
end loop;
commit;
end;
/
select sum(bytes)/1024/1024 mb, count(*) partition_count from dba_segments where segment_name = 'HISTORY';
Применимы ли эти результаты к вам?
Есть большая вероятность, что ваши результаты будут разными в вашей системе, в зависимости от ваших данных и того, как ваша система распределяет сегменты. Важно то, что вы должны сами провести такой тест. И имейте в виду, что разделы предназначены для «больших» объемов данных, но слово «большой» явно субъективно.
Ежедневное разбиение на разделы идеально подходит для многих больших таблиц, но я чувствую, что ваша таблица будет лучше работать с разбиением по месяцам.