Ich glaube nicht, dass es eine Frage der Leistung ist, sondern des Managements.
Mit einer separaten Datei pro Tabelle können Sie beispielsweise verschiedene Datenbanken auf verschiedenen Speichergeräten speichern.
Sie können den Fall sehr großer Datenbanken in Dateisystemen behandeln, die keine großen Dateien verarbeiten können (verschieben Sie das Problem zumindest, bis eine Tabelle die Dateigrößenbeschränkung erreicht).
Sie haben kein unkontrolliertes Tablespace-Wachstum. Wenn Sie einige große Tabellen haben, die Sie löschen, ist ibdata
Datei bleibt klein.
Ein Aspekt, der sich auf die Leistung auswirken kann, ist die Fragmentierung von Tabellendaten und Indizes, die pro Tabelle begrenzt sein wird. Aber das muss getestet werden, um bestätigt zu werden.
Warum innodb_file_per_table verwenden?
Weil es einfacher ist, einzelne zu verwalten, da dies auf Dateiebene erfolgen kann. Das bedeutet, dass Sie auch dann, wenn der Server ausgefallen ist, immer noch Daten kopieren können, indem Sie die Tabellendateien kopieren, während die Verwendung eines gemeinsam genutzten Tabellenbereichs bedeutet, entweder alles zu kopieren was unnötig massiv sein kann, oder einen Weg zu finden, den Server zum Laufen zu bringen, um Daten zu extrahieren (Sie wollen die Daten wirklich nicht manuell mit einem Hex-Editor extrahieren).
Jemand hat davor gewarnt, dass Sie .ibd
nicht einfach kopieren und einfügen können Dateien von einem Server auf einen anderen. Das mag stimmen, sollte aber nicht für Backups auf demselben Server gelten (ich verwende den Begriff Backup hier im traditionellen Sinn des Kopierens; d.h. das Ganze nicht drastisch ändern). Außerdem ibdata1
wird beim Start automatisch neu erstellt (wie in der delete ibdata1
Schritt der meisten „Konvertieren in Datei-pro-Tabelle“-Anleitungen). Als solches tun Sie das nicht müssen ibdata1
kopieren zusätzlich zu Ihrem .ibd
Dateien (und ihre entsprechenden .frm
, usw. Dateien).
Wenn Sie versuchen, eine verlorene Tabelle wiederherzustellen, sollte es ausreichen, ihren .ibd
zu kopieren und .frm
Datei sowie information_schema
(was viel ist kleiner als ibdata1
). Auf diese Weise können Sie sie in einen Dummy-Server stecken und Ihre Tabelle extrahieren, ohne das ganze riesige Ding kopieren zu müssen.
Der Anspruch auf bessere Leistung ist jedoch fraglich. … Mit innodb_file_per_table werden mehr Platten-I/O-Operationen benötigt; und dies ist bei komplizierten JOINs und FOREIGN KEY-Einschränkungen von Bedeutung.
Es überrascht nicht, dass die Leistung vollständig von den verwendeten Datenbanken abhängt. Eine Person wird (sogar sehr) unterschiedliche Ergebnisse von einer anderen haben.
Es stimmt, dass es mehr Platten-I/O-Operationen mit Datei-pro-Tabelle geben wird, aber nur geringfügig mehr. Denken Sie darüber nach, wie das System funktioniert.
-
Für eine monolithische Datenbank:
- Server ist gestartet
ibdata1
wird geöffnet- Header und Metadaten werden gelesen
- Strukturen und Metadaten werden im Speicher zwischengespeichert
- Abfragen passieren
- Server greift auf die Platte zu und liest die Daten aus dem bereits geöffneten
ibdata1
- Der Server kann die Daten im Arbeitsspeicher zwischenspeichern
- Server greift auf die Platte zu und liest die Daten aus dem bereits geöffneten
-
Für eine Datenbank pro Tabelle:
- Server ist gestartet
ibdata1
wird geöffnet- Header und Metadaten werden gelesen
- Jeder einzelne
.ibd
Datei wird geöffnet - Header und Metadaten werden aus jedem
.ibd
gelesen Datei - Strukturen und Metadaten werden im Speicher zwischengespeichert
- Abfragen passieren
- Server greift auf die Platte zu und liest die Daten aus dem bereits geöffneten
.ibd
Datei - Der Server kann die Daten im Arbeitsspeicher zwischenspeichern
- Server greift auf die Platte zu und liest die Daten aus dem bereits geöffneten
Sie werden feststellen, dass Sie die Datendateien nicht verschieben können, wenn der Server ausgeführt wird, da der Server offene Handles für sie hat. Dies liegt daran, dass es sie beim Start öffnet und offen lässt. Es öffnet und schließt sie nicht für jede einzelne Abfrage.
Daher gibt es am Anfang, wenn der Server hochfährt, nur einige weitere I/O-Operationen; nicht während es läuft. Weiterhin, während jeder einzelne .ibd
Datei hat ihren eigenen separaten Overhead (Dateisignaturen, Strukturen usw.), sie werden im Speicher zwischengespeichert und nicht für jede Abfrage erneut gelesen. Außerdem werden auch bei einem Shared Tablespace die gleichen Strukturen gelesen, so dass kaum (wenn überhaupt) mehr Speicher benötigt wird.
Hat innodb_file_per_table einen Einfluss auf eine bessere Leistung von mysql?
Tatsächlich kann die Leistung sogar schlechter sein .
Bei Verwendung eines gemeinsam genutzten Tabellenbereichs können Lese- und Schreibvorgänge manchmal/oft kombiniert werden, sodass der Server ein Datenfeld aus mehreren Tabellen auf einmal von ibdata
liest .
Wenn die Daten jedoch auf mehrere Dateien verteilt sind, muss für jede einzelne eine separate E/A-Operation durchgeführt werden.
Dies ist natürlich wieder ganz von der jeweiligen Datenbank abhängig; die tatsächliche Leistungsauswirkung würde von der Größe, der Abfragehäufigkeit und der internen Fragmentierung des gemeinsam genutzten Tabellenbereichs abhängen. Einige Leute bemerken möglicherweise einen großen Unterschied, während andere überhaupt keine Auswirkungen sehen.
Tablespace wird auf einzelnen ibdata geteilt; wie dedizierte Tablespaces für separate Tabellen Speicherplatz sparen können?
Es tut nicht. Wenn überhaupt, erhöht es sich Festplattennutzung etwas.
Ich habe keine 60-GB-Datenbank zum Testen, aber meine „dürftige“ persönliche Datenbank, die meine WordPress-Installation und einige kleine Tabellen für den persönlichen Gebrauch und Entwicklungstests enthält, wog ~ 30 MB, während ich einen gemeinsam genutzten Tabellenbereich verwendete. Nach der Konvertierung in Datei-pro-Tabelle wurde es auf ~ 85 MB aufgebläht. Selbst wenn alles gelöscht und neu importiert wurde, waren es immer noch>60 MB.
Dieser Anstieg ist auf zwei Faktoren zurückzuführen:
-
Das absolute Minimum Größe für
ibdata1
ist – aus irgendeinem Grund – 10 MB, auch wenn Sie nichts alsinformation_schema
haben darin gespeichert. -
Bei einem gemeinsam genutzten Tabellenbereich nur
ibdata1
hat Overhead wie Dateisignaturen, Metadaten usw., aber mit pro Tabelle, jeder einzelne.ibd
Datei hat all das. Das bedeutet, dass insgesamt (selbst bei hypothetischen <10MBibdata1
) wäre etwas größer um mindestens:GetTotalSizeofOverhead() * GetNumTables()
Offensichtlich werden diese nicht riesig sein erhöht (es sei denn, Sie verwenden einen Host, der Ihre Datenbankgröße begrenzt oder sie auf einem Flash-Laufwerk usw. speichert), aber sie erhöhen sich trotzdem, und während durch Umschalten (alle ) Tabelle in Datei pro Tabelle können Sie ibdata1
verkleinern bis zu 10 MB ist die Gesamtsumme immer mehr als es war.
Dies ist mein Grund, IMMER innodb_file_per_table zu verwenden:
Ohne Datei pro Tabelle wird die ibdata-Datei niemals komprimiert oder schrumpft oder verringert sich der Platz. Nicht, wenn Sie eine Zeile löschen, eine Tabelle oder eine Datenbank löschen. Aus 2 GB Daten kann in kürzester Zeit eine 20 GB große Datei werden, wenn Sie ein aktives Warteschlangensystem haben.
Angenommen, Sie möchten vor einer Änderung eine Sicherungskopie Ihrer aktuellen 1-GB-Tabelle erstellen und sie danach löschen. Sie stecken mit einem GB ungenutzten Speicherplatzes in Ihren ibdata fest. Schade.
Es gibt wahrscheinlich endlose Beispiele für Fälle, in denen vorübergehende Maßnahmen die einzelne Datendatei aufblähen, aber es genügt zu sagen, dass es meiner Meinung nach nie einen Grund gibt, innodb_file_per_table
NICHT zu verwendenAuch hier ist ein guter Beitrag zum Lesen:http://code.openark.org/blog/mysql/reasons-to-use-innodb_file_per_table