phpundmysql.de

Partition Exchange mit MySQL 5.6

| Keine Kommentare

Das Problem, welches durch Partition Exchange gelöst wird, sollte jedem bekannt sein, der schon einmal eine größere Datenmenge in Null-Komma-Nix in eine viel abgefragte Datenbank schaufeln musste: Zugreifende Anwender sollen von dem Ladevorgang nichts mitbekommen, solange er nicht vollständig abgeschlossen ist – weder soll die Performance der Zugriffe maßgeblich beeinträchtigt werden, noch sollen die bereits geladenen Teile in den Anfrageergebnissen auftauchen.

Das Vorgehen beim Partition Exchange ist denkbar einfach. Die Daten werden nicht gleich in die partitioinierte Zieltabelle geladen, sondern in eine strukturgleiche unabhängige Tabelle. Der Ladevorgang wird daurch von den Abfragen entkoppelt und kann ruhig mehr Zeit in Anspruch nehmen. Ist das Laden vollständig abgeschlossen, legt man eine leere Partition in der Zieltabelle an und gibt dem Server zum Schluss das Kommando, die temporäre Tabelle und die leere Partition zu tauschen.

Zur Verdeutlichung ein Beispiel: Die Tabelle umsaetze beinhaltet Käufe eines großen Einzelhandelsgeschäfts. Jeden Tag kommen im Geschäft 50.000 Transaktionen hinzu, so dass das Datenvolumen – bei unterstellten 20 Arbeitstagen – pro Monat um 1 Mio. Datensätze steigt. Die Tabelle umsaetze dient dem Reporting und wird monatlich im Batch aktualisiert, eine Partitionierung erfolgt auf Basis des Umsatztages per PARTITION BY RANGE (datum).

CREATE TABLE IF NOT EXISTS `umsaetze` (
  `kunde_id` int(11) NOT NULL,
  `datum` date NOT NULL,
  `umsatz` decimal(10,2) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY RANGE (MONTH(datum))
(PARTITION jan VALUES LESS THAN (2) ENGINE = InnoDB,
 PARTITION feb VALUES LESS THAN (3) ENGINE = InnoDB) */;

Die Umsätze für März kommen als CSV Datei im Format

kunde_id;datum;umsatz
99141;2012-03-15;54689.4
20218;2012-03-16;38086.58
89814;2012-03-06;94034.74

Da das Format zur Umsatztabelle passt, wird nun noch eine strukturgleiche Tabelle benötigt, die sich denkbar einfach erzeugen und befüllen lässt:

CREATE TABLE maerz_umsaetze LIKE umsaetze;
ALTER TABLE maerz_umsaetze REMOVE PARTITIONING;
LOAD DATA INFILE 'mar.csv' INTO TABLE maerz_umsaetze FIELDS TERMINATED BY ';' LINES TERMINATED BY '\r\n' IGNORE 1 LINES;

Bei diesem Statement ist zu beachten, dass die Datei mar.csv im Daten-Verzeichnis der aktiven Datenbank liegen muss, ansonsten ist ein korrekter Pfad anzugeben. Da die Datei eine Kopfzeile mit Spaltennamen besitzt, wird zudem die erste Zeile ausgelassen.
Um die Daten in umsaetze zu integrieren, wird zuerst eine leere März-Partition angelegt und sofort danach mit der Tabelle maerz_umsaetze ersetzt:

ALTER TABLE umsaetze ADD PARTITION (PARTITION mar VALUES LESS THAN (4));
ALTER TABLE umsaetze EXCHANGE PARTITION mar WITH TABLE maerz_umsaetze;

Obwohl die Tabelle/Partition mehrere Tausend Datensätze umfasst, ist der Prozess beinahe sofort abgeschlossen:

Query OK, 0 rows affected (0.32 sec)

Schreibe einen Kommentar