Frage

Ich gründe eine große Datenbank, die statistischen Berichte aus dem eingehenden Daten generieren.
Das System wird zum größten Teil arbeitet wie folgt:

  1. Ungefähr 400k-500k Zeilen - etwa 30 Säulen, meist varchar (5-30) und Datumzeit - werden jeden Morgen hochgeladen werden. Seine etwa 60 MB, während in der Flat-File-Form, sondern wächst steil in der DB mit der Zugabe von geeigneten Indizes.
  2. Verschiedene Statistiken werden aus dem Tag Daten erzeugt werden.
  3. Berichte aus diesen Statistiken generiert und gespeichert werden.
  4. Aktuelle Datensatz wird in einer partitionierten Historientabelle kopiert werden.
  5. Im Laufe des Tages, der aktuelle Datensatz (die kopiert wurde, nicht bewegt) können von Endanwendern für Informationen abgefragt werden, die nicht wahrscheinlich sind Konstanten, sondern Beziehungen zwischen den Feldern.
  6. Benutzer auf Anfrage spezielle Suchanfragen aus der History-Tabelle, aber die Anfragen werden von einem DBA gefertigt werden.
  7. vor dem Upload am nächsten Tag, die aktuelle Datentabelle wird abgeschnitten.

Dies wird im Wesentlichen Version 2 unseres bestehenden Systems sein.

Im Moment verwenden wir MySQL 5.0 MyISAM-Tabellen (InnoDB wurde auf Raumnutzung allein zu töten) und stark auf # 6 und # 4 leiden. # 4 ist derzeit nicht als 5.0 eingereicht partitioniert nicht unterstützt wird. Um rund um die enorme Menge an Zeit, um (Stunden und Stunden) seine Aufnahme Aufzeichnungen in der Geschichte einfügen, sind wir jeden Tag zu einer nicht indizierten history_queue Tabelle zu schreiben, und dann an den Wochenenden während unserer langsamste Zeit, das Schreiben in die Warteschlange des History-Tabelle. Das Problem ist, dass alle historischen Abfragen in der Woche erzeugt werden möglicherweise mehrere Tage hinter dann. Wir können nicht die Indizes auf der historischen Tabelle reduzieren oder seine Anfragen werden unbrauchbar.

Wir ziehen auf jeden Fall mindestens MySQL 5.1 für die nächste Version (wenn wir mit MySQL zu bleiben), aber stark unter Berücksichtigung PostgreSQL. Ich weiß, dass Debatte zum Tod geschehen ist, aber ich habe mich gefragt, ob jemand irgendwelche Ratschläge relevant zu dieser Situation hatte. Der größte Teil der Forschung rund um die Nutzung der Website. Die Indizierung ist wirklich unser Rindfleisch mit MySQL und es scheint, wie PostgreSQL kann helfen, uns aus durch partielle Indizes und Indizes auf Basis von Funktionen.

Ich habe Dutzende von Artikeln über die Unterschiede zwischen den beiden zu lesen, aber die meisten sind alt. PostgreSQL wurde „weiter fortgeschritten, aber langsamer“ lang markiert - ist, dass nach wie vor im Allgemeinen der Fall zu vergleichen MySQL 5.1 auf PostgreSQL 8.3 oder ist es jetzt ausgeglichener?

Kommerzielle Datenbanken (Oracle und MS SQL) ist einfach keine Option - obwohl ich wünschte, Oracle war

.

Hinweis auf MyISAM vs InnoDB für uns: Wir liefen InnoDB und für uns, wir fanden es viel langsamer, wie 3-4 mal langsamer. ABER, wir waren auch viele neueren MySQL und ehrlich gesagt bin ich nicht sicher, ob wir db passend für InnoDB abgestimmt hatten.

Wir sind mit einem sehr hohen Grad an Verfügbarkeit in einer Umgebung ausgeführt wird - Batterie-Backup, Failover-Netzwerk-Verbindungen, Backup-Generatoren, voll redundante Systeme, etc. So die Integrität Bedenken mit MyISAM wurden gewogen und als akzeptabel

In Bezug auf 5.1: Ich habe die Stabilitätsprobleme betreffen mit 5,1 gehört. Generell gehe ich davon aus, dass jeder vor kurzem (innerhalb der letzten 12 Monate) Stück Software nicht rock-solid stabil ist. Die aktualisierte Funktion in 5.1 festgelegt ist einfach zu viel ist die Chance darauf zu verzichten gegeben, um das Projekt zu Re-Engineering.

In Bezug auf PostgreSQL gotchas: COUNT (*) ohne where-Klausel ist ein ziemlich seltener Fall für uns. Ich habe nicht erwarten, dass dies ein Problem sein. COPY FROM ist nicht annähernd so flexibel wie LOAD DATA INFILE aber ein Zwischenladetisch behebt das. Meine größte Sorge ist der Mangel an INSERT IGNORE. Wir haben es oft verwendet, wenn eine Bearbeitungstisch bauen, so dass wir in zweimal mehrere Datensätze setzen vermeiden konnte und dann nur um einige dups zu entfernen am Ende eine riesige Gruppe zu tun haben. Ich denke, es ist nur selten genug für den Mangel an sie verwendet werden tolerable.

War es hilfreich?

Lösung

Meine Arbeit versucht, ein Pilotprojekt auf historische Daten aus einem ERP-Setup zu migrieren. Die Größe der Daten ist auf der kleinen Seite, nur 60Gbyte mit über ~ 21 Millionen Zeilen, die größte Tabelle mit 16 Millionen Zeilen. Es gibt eine zusätzliche ~ 15 Millionen Zeilen warten in das Rohr kommen, aber der Pilot aufgrund anderer Prioritäten auf Eis gelegt worden. Der Plan war PostgreSQLs „Job“ Einrichtung zu verwenden, um Abfragen zu planen, die Daten auf einer täglichen Basis für den Einsatz in der Analytik regenerieren würde.

Ausführen von einfachen Aggregaten über die große 16-Millionen-Rekord-Tabelle, das erste, was ich aufgefallen ist, wie empfindlich es auf die Menge an RAM zur Verfügung steht. Eine Erhöhung des RAM an einer Stelle für ein Jahr im Wert von Aggregaten erlaubt, ohne auf sequenziellen Table Scans greifen zu müssen.

Wenn Sie sich entscheiden, PostgreSQL zu verwenden, würde ich die Config-Datei sehr empfehlen Neuabstimmung, wie es mit den meisten konservativen Einstellungen möglich zu versenden neigt (so dass es auf Systeme mit wenig Arbeitsspeicher ausgeführt wird). Tuning dauert ein wenig, vielleicht ein paar Stunden, aber wenn man es zu einem Punkt, wo Antwort akzeptabel ist, setzen Sie ihn einfach und vergessen Sie es.

Wenn Sie die serverseitige Abstimmung haben getan (und es ist alles über das Gedächtnis, Überraschung!) Sie Ihre Aufmerksamkeit auf Ihre Indizes drehen werden. Indexierung und Abfrage Planung erfordert auch ein wenig Mühe, aber einmal festgelegt werden Sie es effektiv sein finden. Partielle Indizes ist ein nettes Feature für die Datensätze zu isolieren, die „edge-case“ Daten in ihnen, ich diese Funktion sehr empfehlen, wenn Sie Ausnahmen in einem Meer von ähnlichen Daten suchen.

Schließlich verwenden den Tabellenbereich Funktion, um die Daten auf einem schnellen Laufwerk-Array zu verlagern.

Andere Tipps

In meiner praktischen Erfahrung muss ich sagen, dass postgresql hatte eine ziemlich Leistungssprung von 7.x / 8,0-8,1 (für unsere Anwendungsfälle in einigen Fällen 2x-3x schneller), 8,1 bis 8,2 die Verbesserung war kleiner, aber immer noch spürbar. Ich weiß nicht, die Verbesserungen zwischen 8.2 und 8.3, aber ich erwarte, dass es auch einige Leistungsverbesserung ist, haben ich es bisher getestet.

In Bezug auf Indizes, würde ich empfehlen, diejenigen zu fallen, und sie erst wieder erstellen, nachdem die Datenbank mit Daten füllen, es ist viel schneller.

Weitere den Mist aus Ihrer postgresql Einstellungen verbessern, gibt es so viel Gewinn daraus. Die Standardeinstellungen sind zumindest sinnvoll, jetzt, in pre 8,2 mal pg für den Betrieb auf einem PDA optimiert wurde.

In einigen Fällen, besonders wenn Sie Abfragen kompliziert haben, können sie verschachtelte Schleifen in den Einstellungen deaktivieren helfen, die pg Kräfte, die auf Ihre Fragen eine bessere Leistung Ansätze zu verwenden.

Ach ja, habe ich gesagt, dass Sie für postgresql gehen?

(Eine Alternative wäre, Firebird, die nicht so flexibel ist, aber in meiner Erfahrung ist es in einigen Fällen der Durchführung viel besser als MySQL und PostgreSQL)

Nach meiner Erfahrung Inodb ist slighly schneller für wirklich einfache Abfragen, pg für komplexere Abfragen. MyISAM ist wahrscheinlich sogar noch schneller als InnoDB zum Abruf, aber vielleicht langsamer für die Indizierung / Index Reparatur.

Diese meist varchar Felder, indizieren Sie sie mit char (n) Indizes?

Können Sie einige von ihnen normalisieren? Es wird Sie auf dem Umschreiben kosten, aber kann einige Zeit auf nachfolgenden Abfragen als Zeilengröße verringert speichern, so dass mehr Zeilen in den Speicher zu einer Zeit passen.

ON EDIT:

OK, also Sie haben zwei Probleme, Abfragezeit gegen die sich täglich, und die Geschichte zu aktualisieren, nicht wahr?

Zum zweiten: in meiner Erfahrung, mysql myism ist schlecht Neuindexierung. Auf Tabellen die Größe der täglichen (0,5 bis 1 M Aufzeichnungen, mit ziemlich breit (denormalized Flacheingabe) Aufzeichnungen), fand ich es schneller war die Tabelle neu zu schreiben als setzen und für die Wieder Indizierung und damit verbundene Platten Dreschen zu warten.

Also die Macht oder auch nicht helfen:

create new_table select * from old_table ;

kopiert die Tabellen aber keine Indizes.

Dann, wie sie normalerweise die neuen Datensätze einzufügen. Erstellen Sie dann den Indizes auf neue Tabelle, eine Weile warten. Drop alte Tabelle, und benennen Sie neue Tabelle alte Tabelle.

Edit: Als Antwort auf die vierte Bemerkung: Ich weiß es nicht, dass MyIsam immer so schlecht ist. Ich weiß, in meinem Fall, ich war schockiert , wie viel schneller die Tabelle zu kopieren und dann war der Index hinzufügen. Wie es geschah, tat ich etwas Ähnliches, was du getan hast, das Kopieren von großen denormalisierter flache Dateien in der Datenbank, und dann die Daten Renormalisieren. Aber das ist eine Anekdote, keine Daten. ;)

(Ich denke auch, fand ich, dass insgesamt InnoDb schneller war, da ich so viel Einfügen als anfragende tat. Ein ganz besonderer Fall von Datenbanknutzung.)

Beachten Sie, dass das Kopieren mit einer ausgewählten a. *, B.Wert als foo beitreten ... war auch schneller als ein Update a.foo = B.Wert ... verbinden, die, wie das Update war auf eine indizierte folgt Spalte.

Was mir nicht klar ist, wie komplex die analytische Verarbeitung ist. In meiner Meinung nach, zu verarbeiten 500K Datensätze mit nicht so ein großes Problem sein, in Bezug auf die analytische Verarbeitung ist es ein kleines Recordset.

Auch wenn es sich um eine komplexe Aufgabe ist es, wenn Sie es über Nacht verlassen können abzuschließen (da es ein täglicher Prozess ist, wie ich aus Ihrem Beitrag verstanden), sollte es dennoch genug sein.

Im Hinblick auf die in Folge Tabelle würde ich die Indizes der Tabelle nicht reduzieren. Auch hier können Sie das Laden über Nacht tun, einschließlich Indizes zu aktualisieren, und haben die Folge, aktualisierten Daten für den Einsatz bereit am Morgen eingestellt, mit schnellerem Zugriff als bei rohen Tabellen (nicht indiziert).

Ich sah PosgreSQL in einem Data-Warehouse wie Umgebung verwendet wird, auf der Setup-Arbeit I (Datentransformation Jobs über Nacht) und ohne Performance Beschwerden beschrieben haben.

Ich würde für PostgreSQL gehen. Sie müssen zum Beispiel partitionierten Tabellen, die seit mindestens 2005 in einem stabilen Postgres-Versionen sind - in MySQL es ein Novum ist. Ich habe über Stabilitätsprobleme in neuen Funktionen von 5,1 . Mit MyISAM haben Sie keine referentielle Integrität, Transaktionen und den gleichzeitigen Zugriff leidet viel - lesen Sie diesen Blog-Eintrag „ mit MyISAM in Produktion " für mehr.

Und Postgres ist viel schneller auf komplizierte Abfragen, die für Ihre # 6 gut sein wird. Es gibt auch eine sehr aktive und hilfreiche Mailingliste rel="nofollow, wo Sie Unterstützung auch von bekommen < a href = "http://www.postgresql.org/community/contributors/" rel = "nofollow noreferrer"> Kern Postgres Entwickler kostenlos. Es hat einige gotchas though.

Die Infobright Menschen scheinen dabei einige interessante Dinge in dieser Richtung zu werden:

http://www.infobright.org/

- psj

Wenn Oracle keine Option, da die Kostenfragen betrachtet, dann Oracle Express Edition kostenlos zur Verfügung steht (wie in Bier). Es hat eine Größe Einschränkungen, aber wenn man die Geschichte nicht halten Sie rund um zu lange jedenfalls, es sollte kein Problem sein.

Überprüfen Sie Ihre Hardware. Sind maxing Sie den IO? Haben Sie Puffer richtig konfiguriert? Ist Ihre Hardware richtig bemessen? Speicher für die Pufferung und schnellen Festplatten sind die Schlüssel.

Wenn Sie zu viele Indizes haben, wird es Einsätze langsam im Wesentlichen nach unten.

Wie geht es Ihnen Ihre Einsätze? Wenn Sie tun, einen Datensatz pro INSERT-Anweisung:

INSERT INTO TABLE blah VALUES (?, ?, ?, ?)

und nenne es 500K mal, wird Ihre Leistung saugen. Ich bin überrascht, dass es in Stunden Finishing. Mit MySQL Sie Hunderte oder Tausende von Zeilen gleichzeitig einfügen können:

INSERT INTO TABLE blah VALUES
  (?, ?, ?, ?),
  (?, ?, ?, ?),
  (?, ?, ?, ?)

Wenn Sie tun, ein Einsatz pro Webanfragen, sollten Sie die Protokollierung in das Dateisystem betrachten und Bulk-Einfuhren auf einem crontab tun. Ich habe diesen Entwurf in der Vergangenheit verwendete Einsätze zu beschleunigen. Es bedeutet auch, dass Ihre Web-Seiten sind nicht abhängig von dem Datenbankserver.

Es ist auch viel schneller LOAD DATA INFILE zu verwenden, um eine CSV-Datei zu importieren. Siehe http://dev.mysql.com/doc/refman /5.1/en/load-data.html

Die andere Sache, kann ich vorschlagen, ist der SQL-Hammer vorsichtig sein - Sie können nicht SQL Nägel haben. Haben Sie darüber nachgedacht, ein Tool wie Pig oder Hive optimierte Datensätze für Ihre Berichte zu generieren?

EDIT

Wenn Sie Probleme Batch-Import von 500K Datensätze haben sollten, müssen Sie irgendwo gefährden. Ich würde einige Indizes auf Ihrer Master-Tabelle löschen, erstellen Sie dann optimierten Sichten auf die Daten für jeden Bericht.

Haben Sie mit dem myisam_key_buffer Parameter versucht zu spielen? Es ist sehr wichtig in der Indexaktualisierungsgeschwindigkeit.

Auch wenn Sie Indizes für Datum, ID, etc., welche Spalten korreliert sind, können Sie tun:

INSERT INTO archive SELECT .. FROM current ORDER BY id (or date)

Die Idee ist es, die Reihen um, in diesem Fall die Indexaktualisierung ist viel schneller einzufügen. Dies ist natürlich nur für die Indizes arbeitet, die mit der ORDER BY zustimmen ... Wenn Sie einige eher zufällig Spalten haben, dann werden diejenigen, die nicht geholfen werden.

  

aber stark unter Berücksichtigung PostgreSQL.

Sie sollten es auf jeden Fall testen.

  

es scheint, wie PostgreSQL uns helfen kann basierend auf Funktionen durch partielle Indizes und Indizes aus.

Ja.

  

Ich habe Dutzende von Artikeln über die Unterschiede zwischen den beiden zu lesen, aber die meisten sind alt. PostgreSQL ist seit langem mit „weiter fortgeschritten, aber langsamer?“ - ist, dass nach wie vor im Allgemeinen der Fall zu vergleichen MySQL 5.1 auf PostgreSQL 8.3 oder ist es ausgeglichener jetzt

Nun, das hängt davon ab. Wie bei jeder Datenbank,

  • Wenn Sie nicht wissen die Konfiguration und TUNE IT IT wird sich nur langsam
  • Wenn Ihre Hardware nicht bis zur Aufgabe ist, wird es langsam

Einige Leute, die mysql gut kennen und wollen Postgres versuchen Faktor nicht in der Tatsache, dass sie brauchen einige Dinge neu zu lernen und die Dokumentation zu lesen, als Ergebnis ein wirklich schlecht konfigurierte Postgres gebenchmarkt ist, und das kann sein ziemlich langsam.

Für Web-Nutzung, habe ich einen gut konfigurierte Postgres gebenchmarkt auf einem Low-End-Server (Core 2 Duo, SATA-Disk) mit einem benutzerdefinierten Benchmark Forum, das ich geschrieben habe und es ausspucken mehr als 4000 Foren Webseiten pro Sekunde, sättigt den Gigabit-Ethernet-Verbindung des Datenbankservers. Also, wenn Sie wissen, wie es zu benutzen, kann es schnell zu schreien werden (InnoDB war viel langsamer aufgrund Parallelitätsprobleme). „MyISAM ist schneller für kleine einfache wählt“ wird insgesamt Stier, wird zappen Postgres eine „kleine einfache wählen“ in 50 bis 100 Mikrosekunden.

Nun, für Ihre Nutzung, Sie kümmern sich nicht um das;)

Sie kümmern uns um die Möglichkeiten, um Ihre Datenbank kann Big Aggregate berechnen und Big schließt sich, und eine richtig konfigurierte Postgres mit einem guten IO-System wird in der Regel gegen eine MySQL-System auf diejenigen gewinnen, weil der Optimierer viel klüger ist, und hat viel mehr beitreten / Aggregat-Typen zur Auswahl.

  

Meine größte Sorge ist der Mangel an INSERT IGNORE. Wir haben es oft verwendet, wenn eine Bearbeitungstisch bauen, so dass wir in zweimal mehrere Datensätze setzen vermeiden konnte und dann nur um einige dups zu entfernen am Ende eine riesige Gruppe zu tun haben. Ich denke, es ist nur selten genug für den Mangel an früher erträglich sein.

Sie können eine GROUP BY verwenden, aber wenn Sie in eine Tabelle einfügen wollen nur Datensätze, die nicht bereits vorhanden sind, können Sie dies tun:

INSERT INTO target SELECT .. FROM source LEFT JOIN target ON (...) WHERE target.id IS NULL

In Ihrem Anwendungsfall Sie keine Parallelität Probleme haben, so dass gut funktioniert.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top