2016-07-07 30 views
1

Kontext: Ich erstelle eine Multithread-Anwendung, die Zeilen sehr häufig einfügen/aktualisieren wird.MyISAM vs InnoDB für schnelle Einfügungen und einen zusammengesetzten eindeutigen Schlüssel

Ursprünglich hatte ich die folgende Tabelle:

#TABLE 1 
CREATE TABLE `example` (
    `id` BIGINT(20) NOT NULL, 
    `state` VARCHAR(45) NOT NULL, 
    PRIMARY KEY (`id`, `state`)) 
ENGINE = MyISAM; 

Doch nach einigen Recherchen fand ich, dass MySQL Sperren auf Tabellenebene für MyISAM-Tabellen erlauben nur eine Sitzung verwendet diese Tabellen zu einer Zeit (source) zu aktualisieren. Nicht gut für eine Multithread-Anwendung, die häufige Änderungen an der Tabelle vornimmt.

Als solche wurde vorgeschlagen, dass ich von einem zusammengesetzten Primärschlüssel zu einem automatisch generierten Primärschlüssel mit einem eindeutigen Index für ID/Status wechseln. Dies würde schnelle Einfügungen ermöglichen, während immer noch die einzigartige Kombination der ID/des Zustandes durchgesetzt wird.

#TABLE 2 
CREATE TABLE `example` (
    `key` BIGINT(20) NOT NULL, 
    `id` BIGINT(20) NOT NULL, 
    `state` VARCHAR(45) NOT NULL, 
    PRIMARY KEY (`key`), 
    UNIQUE INDEX `ID_STATE` (`id` ASC, `state` ASC)) 
ENGINE = MyISAM; 

InnoDB vermeidet jedoch Sperren Tabelle und verwendet stattdessen Sperren auf Zeilenebene (source), so dachte ich an die folgende Umschaltung:

#TABLE 3 
CREATE TABLE `example` (
    `key` BIGINT(20) NOT NULL, 
    `id` BIGINT(20) NOT NULL, 
    `state` VARCHAR(45) NOT NULL, 
    PRIMARY KEY (`key`), 
    UNIQUE INDEX `ID_STATE` (`id` ASC, `state` ASC)) 
ENGINE = InnoDB; 

Aber nach etwa InnoDB lesen, ich entdeckte InnoDB organisiert Daten, die einen gruppierten Index und sekundäre Indizes verwenden, erfordern mehrere Suchvorgänge. Eine für den Sekundärindex und eine weitere für den Primärschlüssel (source). Als solche ich debattieren die folgenden Schalt:

#TABLE 4 
CREATE TABLE `example` (
    `id` BIGINT(20) NOT NULL, 
    `state` VARCHAR(45) NOT NULL, 
    PRIMARY KEY (`id`, `state`)) 
ENGINE = InnoDB; 

Ich frage mich, ob alle meine Annahmen richtig sind:

  1. MyISAM-Tabelle sperrt die gesamte Tabelle für Einfügungen, Aktualisierungen und löscht nur erlaubt, eine Sitzung, um diese Tabellen auf einmal zu aktualisieren
  2. InnoDB behandelt INSERT mit zusammengesetzten Primärschlüsseln schneller als MyISAM. Dies liegt daran, dass InnoDB im Gegensatz zu MyISAM nicht die gesamte Tabelle zum Durchsuchen und Reservieren eines neuen Primärschlüssels sperrt.
  3. Wenn ich InnoDB verwende, sollte ich einen zusammengesetzten Primärschlüssel anstelle eines zusammengesetzten eindeutigen Index machen, weil ein sekundärer Index mehrere Nachschlagevorgänge erfordert.
  4. I 4 unter Verwendung von Tabelle
+0

(2) ist ein * non sequitur *. – EJP

+0

Sie haben Recht, ich habe es aktualisiert, um besser zu verdeutlichen, was ich meinte. – Rawr

Antwort

3

1-ja, 2-ja, 3-ja, 4-ja werden sollte. Auch

...

  • Haben Sie wirklich brauchen BIGINT? Werden nicht 4 Milliarden Werte in INT UNSIGNED ausreichen? (Und speichern Sie die Hälfte des Platzes.) Vermutlich ist id die PK von einer anderen Tabelle? Wenn ja, müsste sich auch dieser Tisch ändern.
  • Kann state normalisiert werden? Oder in eine ENUM verwandelt? Wieder Platz sparen.

Element 3 ist schlechter als erwähnt, weil zwei eindeutige Schlüssel gesperrt werden müssen.

+0

Können Sie erklären, was Sie mit "schlechter als erwähnt" gemeint haben? Wollen Sie sagen, dass das Erstellen eines zusammengesetzten Sekundärindex mehr als nur zwei Suchvorgänge erfordert? P.S. Gute Punkte alle von ihnen.Ich habe nie daran gedacht, dass "BIGINT (10)" 10 Milliarden und "INT UNSIGNED" 4 Milliarden sind. – Rawr

+0

'BIGINT' ist eine 64-Bit-Zahl" +/- 8 Milliarden Milliarden "; das '(10)' sagt _nothing_. –