Würde die Indexsuche mit char vs varchar merklich schneller sein, wenn alle Werte 36 Zeichen betragen?

30

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 gibt keine Hoffnung, diesen Ansatz zu ändern, jedoch ist die Leistung beim Indexzugriff schlecht. Abgesehen von der Vielzahl von Gründen dies sein könnte, gibt es eine Sache , die ich bemerkte , die weniger als optimal schienen - trotz alles ID - Werte in allen vielen Tabellen genau 36 Zeichen lang sind, ist der Spalt Typ varchar(36), nicht char(36) .

Würde die Änderung der Spaltentypen auf eine feste Länge erhebliche Vorteile für die Indexleistung char(36)bieten , abgesehen von der sehr geringen Zunahme der Anzahl der Einträge pro Indexseite usw.?

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

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

Bohemien
quelle

Antworten:

40

Nein . Nein überhaupt gewinnen . Im Handbuch heißt es ausdrücklich :

Tipp: Bei diesen drei Typen gibt es keinen Leistungsunterschied , abgesehen von erhöhtem Speicherplatz bei Verwendung des Typs mit Leerzeichenauffüllung und einigen zusätzlichen CPU-Zyklen zum Überprüfen der Länge beim Speichern in einer Spalte mit eingeschränkten Längen. Während character(n)einige andere Datenbanksysteme Leistungsvorteile bieten, gibt es in PostgreSQL keinen solchen Vorteil. in der Tat character(n)ist in der Regel die langsamste der drei wegen seiner zusätzlichen Lagerkosten. In den meisten Situationen text oder character varyingsollte stattdessen verwendet werden .

Meine kühne Betonung.

char(n)ist ein weitgehend veralteter, nutzloser Typ. Bleib bei varchar(n). Wenn Sie die Länge nicht erzwingen müssen varcharoder textetwas schneller wären. Sie können keinen Unterschied messen.

Wenn alle Zeichenfolgen genau 36 Zeichen lang sind, wird auch kein Speicherplatz gespart, auch kein winziger. Beide haben genau die gleiche Größe auf der Festplatte und im RAM. Sie können mit pg_column_size()(für einen Ausdruck und für eine Tabellenspalte) testen .

Verbunden:

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

  1. COLLATION- es sei denn, Sie führen Ihren DB mit der Kollatierung "C" aus . Kollatierung 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, COLLATIONRegeln zu befolgen. Verbunden:

    Umfassender Benchmark-Vergleich (unter anderem) der Auswirkungen COLLATE "C"auf die Leistung:

  2. Offensichtlich UUID . Ihre Zeichenfolge sieht verdächtig aus wie eine UUID (32 hexadezimale Ziffern plus 4 Begrenzer). Es wäre viel effizienter, diese als tatsächlichenuuidDatentypzu speichern, der in mehrfacher Hinsicht schneller ist und nur 16 Bytes belegt - im Gegensatz zu 37 Bytes im RAM für entwederchar(36)odervarchar(36)(gespeichert ohne Begrenzer, nur die 32 definierenden Zeichen) oder 33 Bytes auf der Festplatte. Aber Ausrichtung padding würde in Folge 40 in vielen Fällen Bytes oder so.)COLLATIONWäre für den irrelevant seinenuuidDatentyp, zu.

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

    Dies kann hilfreich sein (letzte Kapitel):

    Siehe auch:

Erwin Brandstetter
quelle
Bedeutet dies, dass ein char / varchar (n) mit Längenbeschränkung CPU-Zyklen für die Überprüfung der Einschränkung benötigt, während das Textfeld mit variabler Länge den Text auf weniger zugängliche Weise separat speichert als char, der in diesem Szenario gewinnt und dies ist sogar eine Überlegung wert für sagen wir 10 Millionen Zeilen mit einem Stück Text
PirateApp
1
@PirateApp: gewinnt char(n)fast nie in irgendeiner Hinsicht. Benutze es nicht. Die Datentypen textund varchar(ohne Längenmodifikator) sind binär kompatibel und weisen dieselben Leistungsmerkmale auf. Es gibt historische Gründe, warum beide in Postgres koexistieren. Intern textist der "bevorzugte" Typ unter den Zeichenfolgentypen (der die Funktionstypauflösung beeinflussen kann). Die CPU-Zyklen zur Durchsetzung spielen varchar(n)kaum eine Rolle. Verwenden Sie bei Bedarf eine Längenbeschränkung . Im vorliegenden Fall uuidist der eigentliche Gewinner.
Erwin Brandstetter