Disons que j'ai une table avec des champs A
et B
. Je fais des requêtes régulières sur A
+ B
, alors j'ai créé un index composite sur (A,B)
. Les requêtes sur seulement A
seraient-elles également entièrement optimisées par l'index composite?
De plus, j'ai créé un index sur A
, mais Postgres utilise toujours l'index composite pour les requêtes uniquement A
. Si la réponse précédente est positive, je suppose que cela n’a pas vraiment d’importance, mais pourquoi sélectionne-t-il l’index composite par défaut, si l’ A
indice unique est disponible?
explain analyze
et le texte de la requête?Réponses:
C'est certainement. Nous avons discuté de cela en détail sous cette question connexe:
L'espace est alloué en multiples de
MAXALIGN
, ce qui correspond généralement à 8 octets sur un système d'exploitation 64 bits ou (beaucoup moins commun) à 4 octets sur un système d'exploitation 32 bits. Si vous n'êtes pas sûr, vérifiezpg_controldata
. Cela dépend également des types de données des colonnes indexées (certaines nécessitent un remplissage d'alignement) et du contenu réel.Un index sur, par exemple, deux
integer
colonnes (4 octets chacune) finit généralement par être exactement aussi grand qu'un index sur une seule colonne, où 4 octets supplémentaires sont perdus pour le remplissage d'alignement.Dans ce cas, le planificateur de requêtes n'a pas d'inconvénient à utiliser un index
(a,b)
, comparé à un index(a)
. Et il est généralement préférable que plusieurs requêtes utilisent le même index. La chance pour qu'il (ou une partie de celui-ci) réside dans le cache (rapide) augmente quand il est partagé.Si vous maintenez déjà un index activé
(a,b)
, il n’a aucun sens de créer un autre index uniquement(a)
- à moins qu’il soit nettement plus petit. La même chose est pas vrai pour les(b,a)
contre(a)
. Suivez le lien à la première ligne pour en savoir plus.En venant de la direction opposée, lorsque vous avez besoin d'un index supplémentaire comme celui-ci
(a,b)
, envisagez de supprimer un index existant uniquement(a)
- si possible. Souvent impossible car il s'agit de l'index d'une PK ou d'uneUNIQUE
contrainte. Depuis Postgres 11, vous pouvez vous contenter d’ajouterb
à la définition de la contrainte avec laINCLUDE
clause. Détails dans le manuel.Ou créez le nouvel index sur
(b,a)
pour couvrir les requêtesb
supplémentaires. Pour les seules conditions d'égalité, l'ordre des expressions d'index dans les index btree n'a pas d'importance. C'est le cas, cependant, lorsqu'il s'agit de conditions de distance. Voir:L' inclusion de colonnes supplémentaires dans un index peut présenter des inconvénients , même si cet espace utilise uniquement de l'espace, sinon perdu par l'alignement de remplissage:
Plus sur les mises à jour HOT:
Comment mesurer la taille des objets:
la source
Selon votre question, vous avez une table avec les champs A et B. Si votre requête est:
L'optimiseur choisira l'index composite pour éviter l'extraction de l'accès aléatoire!
la source
C'est dans le cas si vous utilisez juste d'abord dans le prédicat.
Il sera analysé si vous utilisez les premières colonnes de la clé composite et la colonne non-clé de la clé composite.
Pour tromper cela, vous pouvez simplement simuler des prédicats comme celui-ci, puis une colonne non-clé:
[A, B] est votre index, [C] - une autre colonne
Pour utiliser l'index vous écrivez comme:
Il utilisera index uniquement dans le cas où il y a un ou deux prédicats [A] ou [A], [B]. Il ne l'utilisera pas dans l'ordre [B], [A] ou [A], [C]. Pour pouvoir utiliser l'index avec la colonne supplémentaire [C], vous devez appliquer l'index en ordonnant les prédicats comme suit: [A], [B] et [C].
la source
B=B
? Je pense que vous ne réalisez rien et que je rejoins donc toute preuve que ce n'est pas simplement ignoré par l'optimiseurB=B
est effectivement le même queB IS NOT NULL
, ce qui semble déplacé. Certainement pas besoin d'utiliser un index sur(a,b)
.