PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

PostgreSQL:Index auf Länge aller Tabellenfelder erstellen

Um die Größe der Zeile in Textdarstellung zu messen, können Sie einfach die gesamte Zeile in Text umwandeln, was viel schneller ist als das Verketten einzelner Spalten:

SELECT length(profile::text) FROM profile;

Aber es gibt 3 (oder 4) Probleme mit diesem Ausdruck in einem Index:

  1. Die Syntax-Kurzform profile::text wird in CREATE INDEX nicht akzeptiert , müssen Sie zusätzliche Klammern hinzufügen oder auf die Standard-Syntax cast(profile AS text) zurückgreifen

  2. Immer noch das gleiche Problem, das @jjanes bereits besprochen hat :nur IMMUTABLE Funktionen sind in Indexausdrücken erlaubt und wandeln einen Zeilentyp in text um erfüllt diese Anforderung nicht. Sie könnten einen gefälschten IMMUTABLE bauen Wrapper-Funktion, wie Jeff es beschrieben hat.

  3. Es gibt eine inhärente Mehrdeutigkeit (Das gilt auch für Jeffs Antwort!):Wenn Sie einen Spaltennamen haben, der mit dem Tabellennamen identisch ist (was ein häufiger Fall ist), können Sie nicht auf den Zeilentyp in CREATE INDEX verweisen da der Bezeichner immer zuerst in den Spaltennamen aufgelöst wird.

  4. Kleiner Unterschied zu Ihrem Original:Dies fügt dem text Spaltentrenner, Zeilendekorateure und eventuell Escape-Zeichen hinzu Darstellung. Sollte für Ihren Anwendungsfall keine große Rolle spielen.

Allerdings , würde ich eine radikalere Alternative als groben Indikator für die Größe einer Zeile vorschlagen:pg_column_size() . Noch kürzer und schneller und vermeidet Probleme 1 , 3 und 4 :

SELECT pg_column_size(profile) FROM profile;

Ausgabe 2 bleibt aber:pg_column_size() ist auch nur STABLE . Sie können eine einfache und kostengünstige SQL-Wrapper-Funktion erstellen:

CREATE OR REPLACE FUNCTION pg_column_size(profile)
  RETURNS int LANGUAGE sql IMMUTABLE AS
'SELECT pg_catalog.pg_column_size($1)';

und dann wie bei @jjanes beschrieben vorgehen. Weitere Einzelheiten:

Beachten Sie, dass ich die Funktion mit dem Zeilentyp profile erstellt habe als Parameter. Postgres erlaubt das Überladen von Funktionen, weshalb wir denselben Funktionsnamen verwenden können. Wenn wir nun den passenden Zeilentyp an pg_column_size() füttern unsere benutzerdefinierte Funktion entspricht besser der Auflösung des Funktionstyps Regeln und wird anstelle der polymorphen Systemfunktion ausgewählt. Alternativ verwenden Sie einen eigenen Namen und machen die Funktion ggf. auch polymorph ...

Verwandte: