Ich entwickle eine Anwendung in Ruby on Rails mit der PostgreSQL (9.4) -Datenbank. Für meinen Anwendungsfall werden Spalten in Tabellen sehr häufig nachgeschlagen, da die gesamte Anwendung nach sehr spezifischen Attributen in einem Modell sucht.
Ich bin zur Entscheidung darüber , ob eine verwenden integer
Art oder einfach einen typischen String - Typen (zB character varying(255)
, die Standardeinstellung in Rails ist ) für die Spalten, wie ich bin nicht sicher , was der Unterschied in der Leistung auf dem Index sein.
Diese Spalten sind Aufzählungen . Sie haben eine feste Größe für die Anzahl der möglichen Werte, die sie haben können. Die meisten Aufzählungslängen überschreiten nicht 5, was bedeutet, dass der Index während der gesamten Lebensdauer der Anwendung mehr oder weniger festgelegt wird . Somit wären der Ganzzahl- und der Zeichenfolgenindex in der Anzahl der Knoten identisch.
Die zu indizierende Zeichenfolge könnte jedoch etwa 20 Zeichen lang sein, was ungefähr dem 5-fachen der Ganzzahl entspricht (wenn eine Ganzzahl 4 Byte beträgt und die Zeichenfolgen aus reinem ASCII mit 1 Byte pro Zeichen bestehen, gilt dies). Ich weiß nicht, wie Datenbank-Engines Index-Lookups durchführen, aber wenn der String "gescannt" werden muss, bis er genau übereinstimmt , bedeutet dies im Wesentlichen, dass der String-Lookup 5x langsamer ist als ein Integer-Lookup. Der "Scan" bis zur Übereinstimmung für die Integer-Suche würde 4 Bytes statt 20 sein. Dies ist, was ich mir vorstelle:
Der Suchwert ist (Ganzzahl) 4:
Scannen ........................ GEFUNDEN | Datensätze werden abgerufen ... | BYTE_1 | BYTE_2 | BYTE_3 | BYTE_4 | BYTE_5 | BYTE_6 | BYTE_7 | BYTE_8 | ... |
Der Suchwert ist (String) "some_val" (8 Bytes):
Scannen ............................................. .................................... GEFUNDEN | Datensätze werden abgerufen ... | BYTE_1 | BYTE_2 | BYTE_3 | BYTE_4 | BYTE_5 | BYTE_6 | BYTE_7 | BYTE_8 | ... |
Ich hoffe das macht Sinn. Grundsätzlich kann die Ganzzahl, da sie weniger Platz beansprucht, schneller als ihr String-Gegenstück "angeglichen" werden. Vielleicht ist das eine völlig falsche Vermutung, aber ich bin kein Experte, deshalb frage ich euch! Ich nehme an, diese Antwort, die ich gerade gefunden habe, scheint meine Hypothese zu stützen, aber ich möchte sicher sein.
Die Anzahl der möglichen Werte in der Spalte würde sich bei Verwendung beider Werte nicht ändern, sodass sich der Index selbst nicht ändern würde (es sei denn, ich habe der Aufzählung einen neuen Wert hinzugefügt). Gibt es in diesem Fall einen Leistungsunterschied bei der Verwendung von integer
oder varchar(255)
, oder ist die Verwendung eines Integer-Typs sinnvoller?
Der Grund, den ich frage, ist, dass der Rails- enum
Typ Ganzzahlen zu Zeichenfolgenschlüsseln zuordnet, diese jedoch keine benutzerbezogenen Spalten sein sollen. Grundsätzlich können Sie nicht überprüfen, ob der Enum-Wert gültig ist, da ein ungültiger Wert einen verursacht, ArgumentError
bevor Überprüfungen ausgeführt werden können. Die Verwendung eines string
Typs würde Validierungen ermöglichen, aber wenn es Leistungskosten gibt, würde ich mich lieber um das Validierungsproblem kümmern.
varchar(255)
vs. zBvarchar(260)
. Möglicherweise gab es so etwas in SQL Server 6.x, aber dies war lange nicht mehr der Fall.