it-swarm.com.de

Wäre die Indexsuche mit char vs varchar spürbar schneller, wenn alle Werte 36 Zeichen betragen?

Ich habe ein Legacy-Schema (Haftungsausschluss!), Das eine Hash-basierte generierte ID für den Primärschlüssel für alle Tabellen verwendet (es gibt viele). Ein Beispiel für eine solche ID ist:

922475bb-ad93-43ee-9487-d2671b886479

Es besteht keine Hoffnung, diesen Ansatz zu ändern, jedoch ist die Leistung beim Indexzugriff schlecht. Abgesehen von den unzähligen Gründen, die dies sein könnte, ist mir eines aufgefallen, das nicht optimal schien - obwohl alle ID-Werte in allen vielen Tabellen genau 36 Zeichen lang sind, lautet der Spaltentyp varchar(36), - nichtchar(36).

Würde das Ändern der Spaltentypen auf eine feste Länge char(36) irgendwelche signifikanten Indexleistungsvorteile bieten, die über die sehr geringe Zunahme der Anzahl von Einträgen pro Indexseite usw. hinausgehen?

Dh arbeiten Postgres bei Typen mit fester Länge viel schneller als bei Typen mit variabler Länge?

Bitte erwähnen Sie nicht die winzige Speicherersparnis - das ist im Vergleich zu der Operation, die erforderlich ist, um die Änderungen an den Säulen vorzunehmen, keine Rolle.

33
Bohemian

Nein. Überhaupt kein Gewinn . Im Handbuch wird ausdrücklich angegeben :

Tipp: Es gibt keinen Leistungsunterschied zwischen diesen drei Typen , abgesehen von erhöhtem Speicherplatz bei Verwendung des mit Leerzeichen aufgefüllten Typs und einigen zusätzlichen CPU-Zyklen bis Überprüfen Sie die Länge beim Speichern in einer Spalte mit eingeschränkter Länge. Während character(n) in einigen anderen Datenbanksystemen Leistungsvorteile bietet, gibt es in PostgreSQL keinen solchen Vorteil. Tatsächlich ist character(n) aufgrund seiner zusätzlichen Speicherkosten normalerweise die langsamste der drei. In den meisten Situationen sollte stattdessen text oder character varying Verwendet werden .

Meine kühne Betonung.

char(n) ist ein weitgehend veralteter, nutzloser Typ. Bleib bei varchar(n). Ohne eine maximale Länge erzwingen zu müssen, sind varchar oder text ein kleines bisschen schneller. (Sie können keinen Unterschied messen.)

Wenn alle Zeichenfolgen genau 36 Zeichen lang sind, gibt es keinen Speicherplatz, der in beiden Richtungen gespeichert wird, nicht einmal einen winzigen. Beide haben genau die gleiche Größe auf der Festplatte und im RAM. Sie können mit pg_column_size() (in einem Ausdruck und in einer Tabellenspalte) testen.

Und wenn alle Zeichenfolgen muss 36 Zeichen haben, machen Sie es lieber text mit einer CHECK (length(col) = 36) Einschränkung, die genau Länge erzwingt, nicht varchar(36) nur max. Länge.

Verbunden:

Sie haben nicht nach anderen Optionen gefragt , aber ich werde zwei erwähnen:

  1. COLLATION - es sei denn, Sie führen Ihre Datenbank mit der Sortierung "C" aus =. Die Sortierung wird oft übersehen und ist möglicherweise teuer. Da Ihre Zeichenfolgen in einer natürlichen Sprache nicht aussagekräftig zu sein scheinen, macht es wahrscheinlich keinen Sinn, COLLATION Regeln zu befolgen. Verbunden:

    Umfangreicher Benchmark zum Vergleich (unter anderem) der Auswirkungen von COLLATE "C" Auf die Leistung:

  2. [~ # ~] uuid [~ # ~] , offensichtlich. Ihre Zeichenfolge sieht verdächtig aus wie eine UUID (32 hexadezimale Ziffern plus 4 Trennzeichen). Es wäre viel effizienter, diese als tatsächlichen uuid -Datentyp zu speichern, der in mehrfacher Hinsicht schneller ist und nur 16 Bytes belegt - im Gegensatz zu 37 Bytes in RAM für entweder char(36) oder varchar(36) (ohne Trennzeichen gespeichert, nur das 32 definierende Zeichen) oder 33 Bytes auf der Festplatte. Aber Alignment Padding würde dazu führen 40 Bytes in vielen Fällen.) COLLATION wäre auch für den Datentyp uuid irrelevant.

    SELECT '922475bb-ad93-43ee-9487-d2671b886479'::uuid
    

    Dies kann hilfreich sein (letzte Kapitel):

    Siehe auch:

44