Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Szybkie partycjonowanie

Mam partycjonowaną tabelę do rejestrowania niektórych aplikacji. Kilka lat temu podzieliłem tabelę na partycje jedną partycją na miesiąc. Ponieważ zbliżamy się do 2016 roku, czas na dodanie partycji na nowy rok. Tabela podzielona na partycje ma, jako dwie ostatnie partycje, partycję na grudzień 2015 r. i partycję używającą MAXVALUE. Nigdy nie planuję mieć żadnych danych na partycji MAXVALUE. Jest po prostu po to, aby ułatwić operacje SPLIT PARTITION.

W przeszłości dodawałbym partycje z poleceniami podobnymi do następujących:

ALTER TABLE usage_tracking
SPLIT PARTITION usage_tracking_pmax AT (TO_DATE('02/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS))
INTO (PARTITION usage_tracking_p201601, PARTITION usage_tracking_pmax);
ALTER TABLE usage_tracking
SPLIT PARTITION usage_tracking_pmax AT (TO_DATE('03/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS'))
INTO (PARTITION usage_tracking_p201602, PARTITION usage_tracking_pmax);

Powyższe instrukcje SQL podzielą partycję MAXVALUE na dwie partycje. Jest 12 takich poleceń, po jednym na każdy miesiąc.

W tym roku, kiedy próbowałem uruchomić skrypt na rok 2016 w środowisku nieprodukcyjnym, byłem zaskoczony, że wykonanie tych poleceń zajęło około 30 minut. W poprzednich latach ukończyli w kilka sekund. Pamiętaj, że USAGE_TRACKING_PMAX jest puste, więc żadne dane nie muszą być przenoszone do odpowiedniej partycji.

Analizując aktywność mojej sesji wykonującej SPLIT, mogłem wyraźnie zobaczyć zdarzenia oczekiwania pliku db, które były śledzone w tej podzielonej na partycje tabeli. Było oczywiste, że operacja SPLIT odczytuje partycję max, mimo że była pusta.

Poprzednie lata działały dobrze, ale ta baza danych została niedawno uaktualniona do Oracle 12c. Znalazłem informacje o tym, jak wykonać szybką operację podziału partycji w MOS Note 1268714.1, który mówi, że dotyczy to Oracle 10.2.0.3 i nowszych, ale nie miałem żadnych problemów w 11.2.0.4. To prawdopodobnie było tylko głupie szczęście i nie mam bazy danych 11g, aby to sprawdzić, ponieważ wszystkie moje zostały zaktualizowane. W związku z tym zamiast skupiać się na tym, co się zmieniło, po prostu zajmę się problemem i zajmę się swoim dniem.

Zgodnie z notatką MOS, aby wykonać szybki podział partycji na tej pustej partycji, muszę się upewnić, że mam statystyki dotyczące pustej partycji.

Potwierdziłem, że NUM_ROWS to 0 dla tej pustej partycji. Nie musiałem więc obliczać statystyk na partycji. Moja pierwsza operacja SPLIT PARTITION była bardzo szybka, zaledwie kilka sekund. Przegroda była pusta i Oracle o tym wiedziało. Co mnie zaskoczyło, to fakt, że nowa partycja USAGE_TRACKING_P201601 i USAGE_TRACKING_PMAX osiągnęły wartości NULL dla statystyk. Oznaczało to, że wykonanie operacji SPLIT PARTITION dla drugiej nowej partycji zajmie dużo czasu. Oto przykład tego, co mam na myśli. Po pierwsze, widzimy 0 wierszy w partycji maksymalnej wartości.

SQL> select num_rows from dba_tab_partitions
  2  where partition_name='USAGE_TRACKING_PMAX';
 
  NUM_ROWS
----------
         0

Teraz podzielę tę partycję.

SQL> ALTER TABLE usage_tracking
  2  SPLIT PARTITION usage_tracking_pmax AT ( TO_DATE('02/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS') )
  3  INTO (PARTITION usage_tracking_p201601, PARTITION usage_tracking_pmax);
 
Table altered.
Elapsed: 00:00:03.13

Zauważ, że dwie ostatnie partycje nie mają teraz statystyk.

SQL> select num_rows from dba_tab_partitions
  2  where partition_name='USAGE_TRACKING_PMAX';
 
  NUM_ROWS
----------
 
 
SQL> select num_rows from dba_tab_partitions
  2  where partition_name='USAGE_TRACKING_P201601';
 
  NUM_ROWS
----------
 
 

Bez statystyk, następna podzielona partycja do utworzenia partycji z lutego 2016 roku zajmuje dużo czasu.

SQL> ALTER TABLE nau_system.usage_tracking
  2  SPLIT PARTITION usage_tracking_pmax AT (TO_DATE('03/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS'))
  3  INTO (PARTITION usage_tracking_p201602, PARTITION usage_tracking_pmax);
 
Table altered.
Elapsed: 00:27:41.09

Jak mówi notatka MOS, potrzebujemy statystyk na partycji, aby wykonać szybką operację podziału. Rozwiązaniem jest obliczenie statystyk na partycji, a następnie użycie jednego polecenia ALTER TABLE, aby utworzyć wszystkie partycje jednocześnie.

BEGIN
 DBMS_STATS.gather_table_stats (tabname=>'USAGE_TRACKING',
 partname => 'USAGE_TRACKING_PMAX',
 granularity => 'PARTITION');
 END;
 /
ALTER TABLE usage_tracking
SPLIT PARTITION usage_tracking_pmax INTO
 (PARTITION usage_tracking_p201601 VALUES LESS THAN (TO_DATE('02/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS')),
  PARTITION usage_tracking_p201602 VALUES LESS THAN (TO_DATE('03/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS')),
  PARTITION usage_tracking_p201603 VALUES LESS THAN (TO_DATE('04/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS')),
  PARTITION usage_tracking_p201604 VALUES LESS THAN (TO_DATE('05/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS')),
  PARTITION usage_tracking_p201605 VALUES LESS THAN (TO_DATE('06/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS')),
  PARTITION usage_tracking_p201606 VALUES LESS THAN (TO_DATE('07/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS')),
  PARTITION usage_tracking_p201607 VALUES LESS THAN (TO_DATE('08/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS')),
  PARTITION usage_tracking_p201608 VALUES LESS THAN (TO_DATE('09/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS')),
  PARTITION usage_tracking_p201609 VALUES LESS THAN (TO_DATE('10/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS') ),
  PARTITION usage_tracking_p201610 VALUES LESS THAN (TO_DATE('11/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS') ),
  PARTITION usage_tracking_p201611 VALUES LESS THAN (TO_DATE('12/01/2016 00:00:00','MM/DD/YYYY HH24:MI:SS') ),
  PARTITION usage_tracking_p201612 VALUES LESS THAN (TO_DATE('01/01/2017 00:00:00','MM/DD/YYYY HH24:MI:SS') ),
  PARTITION usage_tracking_pmax);

Gdybym pozostawił skrypt do wykonania 12 pojedynczych operacji SPLIT PARTITION, musiałbym ponownie obliczyć statystyki dotyczące maksymalnej partycji między każdą z nich. Użycie jednego polecenia było bardziej wydajne.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Przekaż i zwróć niestandardowy obiekt tablicy w ibatis i oracle w java

  2. Jak korzystać z rownum

  3. Wstawianie/aktualizacja wsadowa MyBatis dla Oracle

  4. ScaleGrid dodaje Oracle Cloud do hostingu zarządzanej bazy danych

  5. Kopia zapasowa online vs offline