PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

PostgreSQL :créer un index sur la longueur de tous les champs de la table

Pour mesurer la taille de la ligne dans la représentation textuelle, vous pouvez simplement convertir la ligne entière en texte, ce qui est beaucoup plus rapide que la concaténation de colonnes individuelles :

SELECT length(profile::text) FROM profile;

Mais il y a 3 (ou 4) problèmes avec cette expression dans un index :

  1. La syntaxe raccourcie profile::text n'est pas accepté dans CREATE INDEX , vous devez ajouter des parenthèses supplémentaires ou utiliser par défaut la syntaxe standard cast(profile AS text)

  2. Toujours le même problème que @jjanes a déjà évoqué :uniquement IMMUTABLE les fonctions sont autorisées dans les expressions d'index et la conversion d'un type de ligne en text ne satisfait pas à cette exigence. Vous pourriez construire un faux IMMUTABLE fonction wrapper, comme Jeff l'a décrit.

  3. Il existe une ambiguïté inhérente (cela s'applique également à la réponse de Jeff !) :si vous avez un nom de colonne identique au nom de la table (ce qui est un cas courant), vous ne pouvez pas référencer le type de ligne dans CREATE INDEX puisque l'identifiant correspond toujours au nom de la colonne en premier.

  4. Différence mineure par rapport à votre original :cela ajoute des séparateurs de colonnes, des décorateurs de lignes et éventuellement des caractères d'échappement au text représentation. Cela ne devrait pas avoir beaucoup d'importance pour votre cas d'utilisation.

Cependant , je suggérerais une alternative plus radicale comme indicateur brut de la taille d'une ligne :pg_column_size() . Encore plus court et plus rapide et évite les problèmes 1 , 3 et 4 :

SELECT pg_column_size(profile) FROM profile;

Problème 2 reste cependant :pg_column_size() est également uniquement STABLE . Vous pouvez créer une fonction wrapper SQL simple et bon marché :

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

puis procédez comme @jjanes décrit. Plus de détails :

Notez que j'ai créé la fonction avec le type de ligne profile comme paramètre. Postgres permet la surcharge de fonctions, c'est pourquoi nous pouvons utiliser le même nom de fonction. Maintenant, lorsque nous alimentons le type de ligne correspondant à pg_column_size() notre fonction personnalisée correspond plus étroitement selon résolution du type de fonction règles et est choisi à la place de la fonction système polymorphe. Vous pouvez également utiliser un nom distinct et éventuellement rendre la fonction également polymorphe ...

Connexe :