Performancevergleich: Pseudo PK vs. Composite Key

Hat jemand eine verlässliche Quelle, der ich entnehmen kann, welche Performanceimplikationen die Wahl eines zusammengesetzten Primärschlüssels gegenüber einem Pseudopriärschlüssel hat? Ich verwende die InnoDB.
Eine Quelle (leider ohne Referenzen) habe ich bereits gefunden:

Ich gehe davon aus, dass die zusammengesetzten Schlüssel keine Nachteile, sondern nur Vorteile bieten. In meinem Fall wäre der zusammengesetzte Schlüssel zumeist aus einem Primärschlüssel (autoinc) einer referenzierten Tabelle und einem weiteren Identifikator zusammengesetzt. Das erspart zusätzlich noch einen Index (den für den Foreign-Key), was auch vorteilhaft ist (http://www.mysqlperformanceblog.com/2012/06/20/find-and-remove-duplicate-indexes/).

Da die Entscheidung elementar ist, möchte ich sie treffen, bevor die Datenbank mit Daten befüllt ist.

[QUOTE=cmrudolph]Hat jemand eine verlässliche Quelle, der ich entnehmen kann, welche Performanceimplikationen die Wahl eines zusammengesetzten Primärschlüssels gegenüber einem Pseudopriärschlüssel hat? Ich verwende die InnoDB.
Eine Quelle (leider ohne Referenzen) habe ich bereits gefunden:

[…][/QUOTE]

Das kann man nicht einfach so beantworten. Da hängt einiges dran, z.B. welche Art von Abfragen (Punktabfragen, Rangequeries usw.) gemacht werden. Dann gibt es das Problem wie in deinem Link, wird gleichzeitig viel in eine Tabelle geschrieben und gelesen bremst man sich selbst aus, da die meisten Indexe ihre Vorteile erst ausspielen wenn mehr gelesen als geschrieben wird ansonsten wird unglaublich viel Zeit damit verbracht ständig den Index zu reorganisieren (v.a. bei den baumartigen). Die Reihenfolge des Einfügens ist auch wichtig, ist es eher geordnet oder sind die Werte zufällig, d.h. müssen eventuell ständig andere Pages reingeladen werden, weil die Abfragen querbeet gehen? Dann ist interessant, welche Art von Index wird intern überhaupt verwendet? Ein “Composite index” ist sehr selten als dementsprechende Datenstruktur implementiert, das sind oft einzelne B-Tree-Varianten für jede der zu indizierenden Spalten deren Ergebnis dann über irgendwelche Ergebnis-Bit-Indexe verschmolzen werden. Und dann gibt’s sicher noch Variablen die mir spontan nicht einfallen.

Übrigens, du kannst auch gleich zu MariaDB greifen, die haben in der 5.x-Version IMHO als Storage Engine “xtraDB” drin, das ist eine InnoDB-Variation die einen erhöhten Fokus auf mehr Geschwindigkeit legt. Alternativ dazu gibt es auch noch TokuDB als Storageengine für MariaDB und MySQL, die verwenden für Indexe eine Art “gestreamten B-Tree”, der lässt wohl nicht so stark bei sehr vielen Inserts nach. Wie es dabei gleichzeitig viele Inserts/Reads steht weiß ich nicht.

Ohne auf die genannten Punkte im Detail einzugehen (vielen Dank an dieser Stelle für die Ausführungen), weil das sowieso immer noch keine Garantie auf eine korrekte Antwort gäbe, kann man also zusammenfassen: im konkreten Fall profilen, aber grundsätzlich kann es so oder so ausgehen. Diese Antwort ist aber besser als meine ursprüngliche Befürchtung, dass zusammengesetzte Schlüssel keine gute Idee sind. Denn bei einem varchar-PK kann man das wohl so pauschalisieren, ohne sich auf allzu dünnes Eis zu begeben.

Bei dem Namen klingelt es bei mir irgendwo tief im Gedächtnis… Soll MariaDB nicht irgendwann einmal MyISAM ablösen und als neue Standardengine in MySQL eingesetzt werden? Ich meine in „High Performance MySQL“ von Schwartz et. al. davon gelesen zu haben. Das ist aber schon ein paar Jährchen her und ich habe danach auch nichts mehr davon gehört. Seitdem habe ich mich aber auch nicht weiter mit MySQL-Performance beschäftigt.

Ich habe auch noch kein konkretes Performanceproblem, daher werde ich wohl vorerst bei InnoDB bleiben. Mal sehen, wo es mich dann hintreibt :wink:

*** Edit ***

Ich erlaube mir mal einen Ausschnitt aus dem Buch zu zitieren („High Performance MySQL“, deutsche Ausgabe der 2. Auflage)

Ich habe kurz gegooglet und MariaDB scheint ein Alternativprodukt zu MySQL geworden zu sein. Da gab es wohl intern ein paar Unstimmigkeiten.

[QUOTE=cmrudolph][…] Denn bei einem varchar-PK kann man das wohl so pauschalisieren, ohne sich auf allzu dünnes Eis zu begeben.
[…]
Ich habe kurz gegooglet und MariaDB scheint ein Alternativprodukt zu MySQL geworden zu sein. […][/QUOTE]

Bei varchars in einem Primärschlüssel sollte man allgemein vorsichtig sein, Strings sind schon von Natur aus langsamer zu verarbeiten, je länger desto schlechter. Vor allem wenn solche Spielchen wie „like %“-Abfragen losgehen. Auch ist Gesamtschlüssellänge relativ begrenzt bei MySQL, wenn es um zusammengesetzte Schlüssel auf varchar-Basis geht. Die Geschwindigkeit der Verwendung hängt auch wieder von bestimmten Dingen ab, wenn z.B. die Key-Strings nicht nur die Schlüssel im Index sind sondern auch in den allermeisten Fällen das Abfrageergebnis selbst, ist man da auch recht zügig unterwegs, weil viele Anfragen aus dem Index bedient werden können.

Und MariaDB ist ein „drop-in“-Replacement-DBMS für MySQL. D.h. es ist 1:1 kompatibel, zumindest in der 5.x Version. Man kann sogar die ganz normalen MySql-Jdbc-Treiber verwenden. Wir haben jedenfalls umgestellt, auch, weil der MySQL-Lizenzdschungel, bzgl. kommerzieller Lizenzen zu undurchsichtig wurde. Aber wenn ich eine neue DB aufsetzen müsste, dann würde ich gleich zu MariaDB greifen, erstens, weil sie, in der Grundinstallation, ihr aufgebohrtes „InnoDB“ (xtradb) verwenden und zweitens allein schon wg. der Lizenzgeschichte. :slight_smile:

Ich habe gestern noch ein wenig länger über die MariaDB gelesen - der Plan die Aria-Storage-Engine in eine spätere MySQL Version zu integrieren ist wohl noch auf der Roadmap.

Die Sache mit den abdeckenden Schlüsseln etc. sind mir noch geläufig (das zitierte Buch habe ich mal durchgearbeitet :wink: ). Nur mit den zusammengesetzten Schlüsseln hatte ich nichts mehr im Kopf.

Ich werde um MySQL wohl nicht herumkommen (MariaDB wäre aufgrund der Kompatibilität noch denkbar), weil ich zum einen mit MySQL „groß“ geworden bin und sie daher am besten kenne, und zum anderen weil ich gerne Amazon RDS nutzen möchte. Das ist dann natürlich noch einmal ein ganz anderes Thema. Wie das dann skaliert und sich von der Leistungsfähigkeit her verhält, muss ich noch testen. Um nicht allzu früh Investitionen tätigen zu müssen, werde ich aber erstmal auf einem „normalen“ Server mit derselben MySQL-Version arbeiten, bis das System dann produktiv geht.