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

L'index PostgreSQL n'est pas utilisé pour la requête sur les plages d'adresses IP

Essayez un index multicolonne, mais avec un ordre inversé sur la deuxième colonne :

CREATE INDEX index_ips_begin_end_ip_num ON ips (begin_ip_num, end_ip_num DESC);

L'ordre n'est généralement pas pertinent pour un index à une seule colonne, car il peut être parcouru en arrière presque aussi rapidement. Mais c'est important pour les index multicolonnes.

Avec l'index que je propose, Postgres peut scanner la première colonne et trouver l'adresse, où le reste de l'index remplit la première condition. Ensuite, il peut, pour chaque valeur de la première colonne, renvoyer toutes les lignes qui remplissent la deuxième condition, jusqu'à ce que la première échoue. Passez ensuite à la valeur suivante de la première colonne, etc.
Ce n'est toujours pas très efficace et Postgres peut être plus rapide en scannant simplement la première colonne d'index et en filtrant pour la seconde. Tout dépend de la distribution de vos données.

Dans tous les cas, CLUSTER en utilisant l'index multicolonne d'en haut peut performances d'aide :

CLUSTER ips USING index_ips_begin_end_ip_num

De cette façon, les candidats remplissant votre première condition sont regroupés sur les mêmes pages de données ou sur des pages adjacentes. Peut grandement améliorer les performances si vous avez beaucoup de lignes par valeur de la première colonne. Sinon, il n'est guère efficace.
(Il existe également des outils externes non bloquants à cet effet :pg_repack ou pg_squeeze.)

En outre, l'autovacuum est-il en cours d'exécution et configuré correctement ou avez-vous exécuté ANALYZE sur la table? Vous avez besoin de statistiques actuelles pour Postgres afin de choisir les plans de requête appropriés.

Ce qui serait vraiment utile ici, c'est un index GiST pour une int8range colonne, disponible depuis PostgreSQL 9.2.

Lectures complémentaires :

  • Optimisation des requêtes sur une plage d'horodatages (deux colonnes)

Si vos plages IP peuvent être couvertes par l'un des types de réseaux intégrés inet ou cidr , pensez à remplacer vos deux bigint Colonnes. Ou, mieux encore, regardez le module supplémentaire ip4r par Andrew Gierth (pas dans la distribution standard. La stratégie d'indexation change en conséquence.

À défaut, vous pouvez consulter cette réponse connexe sur dba.SE en utilisant un régime sophistiqué avec des index partiels. Des trucs avancés, mais qui offrent d'excellentes performances :

  • L'index spatial peut-il aider une requête "range - order by - limit" ?