sql >> Database >  >> RDS >> Oracle

Snelle gesplitste partitionering

Ik heb een gepartitioneerde tabel voor het loggen van sommige toepassingen. Een paar jaar geleden heb ik de tabel gepartitioneerd met één partitie per maand. Nu we 2016 naderen, is het tijd voor mij om partities toe te voegen voor het nieuwe jaar. De gepartitioneerde tabel heeft, als laatste twee partities, de partitie voor december 2015 en een partitie die MAXVALUE gebruikt. Ik ben nooit van plan om gegevens in de MAXVALUE-partitie te hebben. Het is er gewoon om SPLIT PARTITION-bewerkingen gemakkelijker te maken.

In het verleden zou ik partities toevoegen met opdrachten die vergelijkbaar zijn met de volgende:

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);

De bovenstaande SQL-instructies splitsen de MAXVALUE-partitie in twee partities. Er zijn 12 van dergelijke commando's, één voor elke maand.

Toen ik dit jaar probeerde het script voor 2016 in een niet-productieomgeving uit te voeren, was ik verrast dat het ongeveer 30 minuten duurde voordat deze opdrachten waren voltooid. In voorgaande jaren waren ze in seconden klaar. Onthoud dat USAGE_TRACKING_PMAX leeg is, dus er hoeven geen gegevens naar een geschikte partitie te worden verplaatst.

Bij het analyseren van de activiteit van mijn sessie die de SPLIT uitvoerde, kon ik duidelijk db file wait-gebeurtenissen zien die naar deze gepartitioneerde tabel werden gevolgd. Het was duidelijk dat de SPLIT-bewerking de max-partitie aan het lezen was, ook al was deze leeg.

Vorige jaren werkte prima, maar deze database is onlangs geüpgraded naar Oracle 12c. Ik vond informatie over het uitvoeren van een snelle splitpartitiebewerking in MOS Note 1268714.1 waarin staat dat dit van toepassing is op Oracle 10.2.0.3 en hoger, maar ik had geen problemen in 11.2.0.4. Het was waarschijnlijk gewoon dom geluk en ik heb geen 11g-database om dit te bekijken, omdat al die van mij zijn geüpgraded. Als zodanig, in plaats van me te concentreren op wat er is veranderd, zal ik het probleem gewoon aanpakken en verder gaan met mijn dag.

Volgens de MOS-notitie moet ik ervoor zorgen dat ik statistieken op de lege partitie heb om een ​​snelle gesplitste partitie op deze lege partitie uit te voeren.

Ik heb bevestigd dat de NUM_ROWS 0 was voor deze lege partitie. Dus ik hoefde geen statistieken op de partitie te berekenen. Mijn eerste SPLIT PARTITION-bewerking was erg snel, slechts een paar seconden. De partitie was leeg en Oracle wist het. Wat me verbaasde was dat de nieuwe partitie, USAGE_TRACKING_P201601 en USAGE_TRACKING_PMAX naar NULL-waarden gingen voor statistieken. Dit betekende dat het uitvoeren van de SPLIT PARTITION-bewerking voor de tweede nieuwe partitie lang zou duren. Hier is een voorbeeld van wat ik bedoel. Ten eerste kunnen we 0 rijen zien in de maximale waardepartitie.

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

Nu zal ik die partitie splitsen.

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

Merk nu op dat de laatste twee partities nu geen statistieken hebben.

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
----------
 
 

Zonder statistieken duurt de volgende gesplitste partitie om de partitie van februari 2016 te maken lang.

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

Zoals de MOS-notitie zegt, hebben we de statistieken op de partitie nodig om een ​​snelle splitsingsbewerking uit te voeren. De oplossing is om statistieken over de partitie te berekenen en vervolgens één ALTER TABLE-opdracht te gebruiken om alle partities tegelijk te maken.

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);

Als ik het script had overgelaten aan het uitvoeren van 12 afzonderlijke SPLIT PARTITION-bewerkingen, dan had ik de statistieken op de maximale partitie tussen elk opnieuw moeten berekenen. Het gebruik van één commando was efficiënter.


  1. Hoe verbinding maken met MySQL op Amazon EC2 vanuit Linux / Mac?

  2. Neo4j Query-taal - Cypher

  3. Leesbare secundairen met een beperkt budget

  4. Blijft de volgorde in een subquery gegarandeerd behouden?