powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Удалить записи с сохранением партиций
18 сообщений из 18, страница 1 из 1
Удалить записи с сохранением партиций
    #39770829
Landgraf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ребята всем привет!

Нужен ваш совет.
Есть таблица размером в 800 Гб. Она партицирована по полю dDate (тип дата). Нужно удалить все записи у которых dDate < 01.01.17.

Учитывая размер таблицы, оператор delete будет работать очень долго.
Думал над таким вариантом:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
Create table MyTable_tmp as
select * from MyTable where dDate >= 01.01.17;

Truncate table MyTable;

Insert into mytable
Select * from mytable_p



Но при таком варианте пропадает партицирование.
Как бы сделать так, чтобы партицирование не слетели по оставшимся записям?
...
Рейтинг: 0 / 0
Удалить записи с сохранением партиций
    #39770831
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LandgrafОна партицирована по полю dDate (тип дата).С какой целью партиционировали таблицу?
...
Рейтинг: 0 / 0
Удалить записи с сохранением партиций
    #39770834
Landgraf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-2-LandgrafОна партицирована по полю dDate (тип дата).С какой целью партиционировали таблицу?

На сколько мне известно, на основании этого поля строятся отчёты. Поле хранит дату загрузки данных. Т.е. за каждый день присутствует N записей.
Таблица была сделана до меня, поэтому почему ее партиционировали.... Для скорости наверное :)
...
Рейтинг: 0 / 0
Удалить записи с сохранением партиций
    #39770853
jan2ary
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Landgraf,

Транкейтить партиции?
...
Рейтинг: 0 / 0
Удалить записи с сохранением партиций
    #39770878
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Помолясь и запасясь бэкапом...

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
create or replace function EVALUATE( s in varchar ) return date as
  res date;
begin
  execute immediate 'begin :x := '||s||'; end;' using out res;
  return res;
end;
/

Function created

create table dropme_t(id, val, dDate)
partition by range(dDate)
interval (interval '11' day)
(partition p1 values less than (date'2000-01-01') segment creation deferred)
as select rownum, 'val'||rownum, date'2016-12-01'+rownum from dual connect by level < 200
;

Table created

select count(*) "ВСЕГО"
     , count(case when ddate <  date'2017-01-01' then 1 end) "Удалить"
     , count(case when ddate >= date'2017-01-01' then 1 end) "Сохранить"
from dropme_t;

     ВСЕГО    Удалить  Сохранить
---------- ---------- ----------
       199         30        169

-- Пограничный раздел
select * from dropme_t partition for (date'2017-01-01');

        ID VAL                                         DDATE
---------- ------------------------------------------- -----------
        25 val25                                       26.12.2016
        26 val26                                       27.12.2016
        27 val27                                       28.12.2016
        28 val28                                       29.12.2016
        29 val29                                       30.12.2016
        30 val30                                       31.12.2016
        31 val31                                       01.01.2017
        32 val32                                       02.01.2017
        33 val33                                       03.01.2017
        34 val34                                       04.01.2017
        35 val35                                       05.01.2017
11 rows selected

-- Поехали...
declare
  l_owner varchar2(100) := USER;
  l_name varchar2(100) := 'DROPME_T';
  l_keep_after date := date'2017-01-01';
  l_partkeyexpression varchar2(2000) := to_char(l_keep_after,q'{"TO_DATE('"yyyy-mm-dd hh24:mi:ss"','yyyy-mm-dd hh24:mi:ss')"}');
  l_meta xmltype;
begin
  l_meta := xmltype(dbms_metadata.get_xml('TABLE',l_name,l_owner));
  for i in (
    select interval_str
    from xmltable('/ROWSET/ROW/TABLE_T/PART_OBJ/PARTOBJ'
           passing l_meta
           columns interval_str path 'INTERVAL_STR'
         )
  )loop
    if i.interval_str is not null then
      execute immediate 'alter table '||l_owner||'.'||l_name||' set interval()';
      execute immediate 'alter table '||l_owner||'.'||l_name||' set interval('||i.interval_str||')';
    end if;
  end loop;
  for i in (
    select 'alter table DROPME_T drop partition '||part_name||' update indexes' stmnt
      from xmltable('/ROWSET/ROW/TABLE_T/PART_OBJ/PART_LIST/PART_LIST_ITEM'
      passing l_meta
      columns part_name path 'SCHEMA_OBJ/SUBNAME'
            , HIBOUNDVAL path 'HIBOUNDVAL'
      ) x
      where evaluate(hiboundval) <= l_keep_after
    ) loop
      execute immediate ''||i.stmnt;
    end loop;
    execute immediate 'alter table '||l_owner||'.'||l_name||' split partition for('||l_partkeyexpression||') at ('||l_partkeyexpression||') update indexes';
    execute immediate 'alter table '||l_owner||'.'||l_name||q'{ drop partition for(date'1900-01-01') update indexes}';
end;
/

PL/SQL procedure successfully completed

-- Итог: 
select count(*) "ВСЕГО"
     , count(case when ddate <  date'2017-01-01' then 1 end) "Удалить"
     , count(case when ddate >= date'2017-01-01' then 1 end) "Сохранить"
from dropme_t;

     ВСЕГО    Удалить  Сохранить
---------- ---------- ----------
       169          0        169

select * from dropme_t partition for (date'2017-01-01');
        ID VAL                                         DDATE
---------- ------------------------------------------- -----------
        31 val31                                       01.01.2017
        32 val32                                       02.01.2017
        33 val33                                       03.01.2017
        34 val34                                       04.01.2017
        35 val35                                       05.01.2017

SQL> 

...
Рейтинг: 0 / 0
Удалить записи с сохранением партиций
    #39772373
Landgraf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ребята всем спасибо за ответы.
В итоге сделал так: Отобрал все необходимые партиций, сделал altet table truncate partition, а потом alter table drop partition.

После того, как удалил данные, теперь нужно уменьшить таблицу, скорректировать уровень HWM.
Я так понимаю можно сделать либо:

Код: plsql
1.
alter table shrink space


Либо
Код: plsql
1.
alter table move



Во втором варианте нужно будет ещё индексы перестроить и пересобрать статистику.

Какой вариант предпочтительней? Таблица весит около 400Гб, партицирована.

В оракловой доке написано, что shrink ужимает неиспользуемое пространство с низу и с верху HWM.
...
Рейтинг: 0 / 0
Удалить записи с сохранением партиций
    #39772381
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Landgrafнужно уменьшить таблицу, скорректировать уровень HWMHWM - это свойство сегмента, а не объекта.
...
Рейтинг: 0 / 0
Удалить записи с сохранением партиций
    #39772386
Landgraf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ElicLandgrafнужно уменьшить таблицу, скорректировать уровень HWMHWM - это свойство сегмента, а не объекта.

Да, есть такое.
...
Рейтинг: 0 / 0
Удалить записи с сохранением партиций
    #39772406
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous,

drop partition update indexes не уменьшит число листьев индекса да и увеличит время выборки по глобальным индексам. UPDATE != REBUILD.

SY.
...
Рейтинг: 0 / 0
Удалить записи с сохранением партиций
    #39772430
Фотография кит северных морей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LandgrafРебята всем спасибо за ответы.
В итоге сделал так: Отобрал все необходимые партиций, сделал altet table truncate partition, а потом alter table drop partition.

После того, как удалил данные, теперь нужно уменьшить таблицу, скорректировать уровень HWM.
Я так понимаю можно сделать либо:

Код: plsql
1.
alter table shrink space


Либо
Код: plsql
1.
alter table move



Во втором варианте нужно будет ещё индексы перестроить и пересобрать статистику.

Какой вариант предпочтительней? Таблица весит около 400Гб, партицирована.

В оракловой доке написано, что shrink ужимает неиспользуемое пространство с низу и с верху HWM. пересоберите global statistics и перестройте global indexes, если есть. больше ничего делать не нужно. truncate partition был лишним.
...
Рейтинг: 0 / 0
Удалить записи с сохранением партиций
    #39772466
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SYdrop partition update indexes не уменьшит число листьев индекса
Не уменьшит - в сравнении с ЧЕМ?
...
Рейтинг: 0 / 0
Удалить записи с сохранением партиций
    #39772468
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymousНе уменьшит - в сравнении с ЧЕМ?

C rebuild.

SY.
...
Рейтинг: 0 / 0
Удалить записи с сохранением партиций
    #39772493
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SYC rebuild.

В сравнении с rebuild глобального индекса по крупной таблице некоторое падение производительности и последующая подчистка orphanned ночным джобиком - сущая ерунда с точки зрения доступности системы.
...
Рейтинг: 0 / 0
Удалить записи с сохранением партиций
    #39772503
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymousпоследующая подчистка orphanned ночным джобиком

В смысле ночным index rebuild? Хорошо когда не 24x7 - у меня удаление soft deleted index keys получаетя только когда release. Проверить насколько дополнительный предикат проверки на orphaned влияет на производительность все руки не доходят.

SY.
...
Рейтинг: 0 / 0
Удалить записи с сохранением партиций
    #39772852
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SYandrey_anonymousпоследующая подчистка orphanned ночным джобиком
В смысле ночным index rebuild?
DBMS_PART.CLEANUP_GIDX
...
Рейтинг: 0 / 0
Удалить записи с сохранением партиций
    #39773101
Фотография Fogel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Коллеги, вы сильно усложняете всё.

Landgraf Ребята всем привет!

Нужен ваш совет.
Есть таблица размером в 800 Гб. Она партицирована по полю dDate (тип дата). Нужно удалить все записи у которых dDate < 01.01.17.

Учитывая размер таблицы, оператор delete будет работать очень долго.
Думал над таким вариантом:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
Create table MyTable_tmp as
select * from MyTable where dDate >= 01.01.17;

Truncate table MyTable;

Insert into mytable
Select * from mytable_p



Но при таком варианте пропадает партицирование.
Как бы сделать так, чтобы партицирование не слетели по оставшимся записям?

Будьте проще.

1. смОтрите скрипт создания вашей оригинальной таблицы (со всеми индексами, констрэйнтами и т.д.).
Копируете его целиком. (заменяете названия индексов и констрэйнтов, дописывая 1 в конце)
2. Вместо
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
create table MyTable
(col1,
col2,
...
colN)
tablespace <какое-то tb>
PARTITION BY RANGE (dDate)
...
и там потом индексы и прочие констрэйнты с комментариями


--
пишете
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
create table MyTable_NEW -- выкидываете весь блок столбцов здесь
tablespace <какое-то tb>
    PARTITION BY RANGE (dDate)
INTERVAL(NUMTOYMINTERVAL(1, 'DAY'))
( PARTITION p0 VALUES LESS THAN (TO_DATE('01-01-2017', 'DD-MM-YYYY')),
PARTITION p1 VALUES LESS THAN (TO_DATE('01-02-2017', 'DD-MM-YYYY'))
)
ENABLE ROW MOVEMENT
as select 
перечисление всех колонок, а не звёздочка
from MyTable
where dDate >= date '2017-01-01';
...
и там потом индексы и прочие констрэйнты с комментариями


3. собираете статистику
Код: plsql
1.
2.
3.
4.
5.
6.
begin
  dbms_stats.gather_table_stats(ownname     => <схема где таблица>,
                                tabname     => 'MYTABLE_NEW',
                                granularity => 'ALL',
                                force       => TRUE);
end;


4. Переименовываете таблички
Код: plsql
1.
2.
alter table MYTABLE rename to MYTABLE_OLD;
alter table MYTABLE_NEW rename to MYTABLE;


4.1 можете сверить данные в табличках всякими интерсектами и минусами для спокойствия души.

5.Дропаете старую таблицу с высвобождением места
Код: plsql
1.
drop table MYTABLE_OLD purge;


6. переименовываете все те индексы и констрэйнты, которым добавили 1 в пункте 1, обратно в оригинальные названия.
Код: plsql
1.
ALTER INDEX index1 RENAME TO oldnameindex; 


как-то так.
без лишней головной боли, с сохранением партиций и прочей структуры таблицы, корректным высвобождением места (без "хвостов" от шринкования ) и т. д., и т. п. ...
...
Рейтинг: 0 / 0
Удалить записи с сохранением партиций
    #39773122
Фотография кит северных морей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FogelБудьте проще.
как говорила моя не по годам мудрая соседка по парте классе в шестом, "просто даже мухи не еб-ся".

2e12
...
Рейтинг: 0 / 0
Удалить записи с сохранением партиций
    #39773609
flexgen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FogelКоллеги, вы сильно усложняете всё...

Ты не упомянул о следующих шагах:
1. Не забыть дать все необходимые права на созданные заново таблицы поскольку при переименовании объекта теряются и права на него.
2. Проверить не стали ли объекты, каким-либо образом использующие пересоздаваемые таблицы, инвалидными и, соответственно, перекомпилировать эти объекты.
3. Не забыть про foreign key constraints в других таблицах, завязанные на пересоздаваемые таблицы.
4. И главное - без downtime, пусть даже минимального, все равно не обойтись.
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Удалить записи с сохранением партиций
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]