J'ai une table avec un index multicolonne, et j'ai des doutes sur le bon tri des index pour obtenir les performances maximales sur les requêtes.
Le scénario:
PostgreSQL 8.4, table avec environ un million de lignes
Les valeurs de la colonne c1 peuvent avoir environ 100 valeurs différentes . Nous pouvons supposer que les valeurs sont réparties uniformément, nous avons donc environ 10000 lignes pour chaque valeur possible.
La colonne c2 peut avoir 1000 valeurs différentes . Nous avons 1000 lignes pour chaque valeur possible.
Lors de la recherche de données, la condition inclut toujours des valeurs pour ces deux colonnes, de sorte que la table a un index multicolonne combinant c1 et c2. J'ai lu l'importance de bien ordonner les colonnes dans un index multicolonne si vous avez des requêtes utilisant une seule colonne pour le filtrage. Ce n'est pas le cas dans notre scénario.
Ma question est celle-ci:
Étant donné que l'un des filtres sélectionne un ensemble de données beaucoup plus petit, pourrais-je améliorer les performances si le premier index est le plus sélectif (celui qui autorise un ensemble plus petit)? Je n'avais jamais réfléchi à cette question avant d'avoir vu les graphiques de l'article référencé:
Image tirée de l'article référencé sur les index multicolonnes .
Les requêtes utilisent les valeurs des deux colonnes pour le filtrage. Je n'ai aucune requête utilisant une seule colonne pour le filtrage. Tous sont: WHERE c1=@ParameterA AND c2=@ParameterB
. Il existe également des conditions comme celle-ci:WHERE c1 = "abc" AND c2 LIKE "ab%"
la source
Si, comme vous le dites, les requêtes impliquant ces 2 colonnes, sont toutes des vérifications d'égalité des deux colonnes, par exemple:
ne vous embêtez pas avec cela. Je doute qu'il y ait une différence et s'il y en a une, elle sera négligeable. Vous pouvez toujours tester bien sûr, avec vos données et les paramètres de votre serveur. Différentes versions d'un SGBD peuvent se comporter légèrement différemment en ce qui concerne l'optimisation.
L'ordre à l'intérieur de l'index importerait pour d'autres types de requêtes, ayant des vérifications d'une seule colonne, ou des conditions d'inégalité, ou des conditions sur une colonne et un regroupement dans l'autre, etc.
Si je devais choisir l'une des deux commandes, je choisirais de mettre la colonne la moins sélective en premier. Considérons un tableau avec des colonnes
year
etmonth
. Il est plus probable que vous ayez besoin d'uneWHERE year = 2000
condition ou d'uneWHERE year BETWEEN 2000 AND 2013
ou d'uneWHERE (year, month) BETWEEN (1999, 6) AND (2000, 5)
.Une requête du type
WHERE month = 7 GROUP BY year
peut être souhaitée (Rechercher les personnes nées en juillet), mais elle le serait moins souvent. Cela dépend bien sûr des données réelles stockées dans votre table. Choisissez une commande pour l'instant, dites le(c1, c2)
et vous pourrez toujours ajouter un autre index plus tard(c2, c1)
.Mise à jour, après le commentaire du PO:
Ce type de requête est exactement une condition de plage sur la
c2
colonne et aurait besoin d'un(c1, c2)
index. Si vous avez également des requêtes de type inverse:alors ce serait bien si vous aviez aussi un
(c2, c1)
indice.la source