sql >> Databasteknik >  >> RDS >> PostgreSQL

PostgreSQL:Skapa index på längden på alla tabellfält

För att mäta storleken på raden i textrepresentation kan du bara casta hela raden till text, vilket är mycket snabbare än att sammanfoga enskilda kolumner:

SELECT length(profile::text) FROM profile;

Men det finns 3 (eller 4) problem med detta uttryck i ett index:

  1. Syntaxens förkortning profile::text accepteras inte i CREATE INDEX , måste du lägga till extra parenteser eller standardsyntaxen cast(profile AS text)

  2. Fortfarande samma problem som @jjanes redan diskuterat :endast IMMUTABLE funktioner är tillåtna i indexuttryck och casting av en radtyp till text klarar inte detta krav. Du kan bygga en falsk IMMUTABLE omslagsfunktion, som Jeff beskrev.

  3. Det finns en inneboende tvetydighet (det gäller även Jeffs svar!):om du har ett kolumnnamn som är samma som tabellnamnet (vilket är ett vanligt fall) kan du inte referera till radtypen i CREATE INDEX eftersom identifieraren alltid löser sig till kolumnnamnet först.

  4. Mindre skillnad mot originalet:Detta lägger till kolumnavgränsare, raddekoratorer och möjligen escape-tecken i text representation. Borde inte spela så stor roll för ditt användningsfall.

Men , skulle jag föreslå ett mer radikalt alternativ som grov indikator för storleken på en rad:pg_column_size() . Ännu kortare och snabbare och undviker problem 1 , 3 och 4 :

SELECT pg_column_size(profile) FROM profile;

Problem 2 kvarstår dock:pg_column_size() är också bara STABLE . Du kan skapa en enkel och billig SQL-omslagsfunktion:

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

och fortsätt sedan som @jjanes beskrivit. Mer information:

Observera att jag skapade funktionen med radtypen profile som parameter. Postgres tillåter funktionsöverbelastning, varför vi kan använda samma funktionsnamn. Nu, när vi matar den matchande radtypen till pg_column_size() vår anpassade funktion matchar bättre enligt upplösning av funktionstyp regler och väljs istället för den polymorfa systemfunktionen. Alternativt kan du använda ett separat namn och eventuellt göra funktionen polymorf också ...

Relaterat:



  1. SQLite exempeldatabas

  2. Mysql:dumpa databas tillsammans med data

  3. Vilka är begränsningarna för MS Access?

  4. MySQL-fel #1005 (kod 150)