Nous avons récemment découvert un problème de performances avec l'un de nos systèmes et je pense avoir le correctif, mais je ne suis pas certain que ma compréhension soit correcte.Est-ce que ma compréhension de "select distinct" est correcte?
Dans la forme la plus simple, nous avons un tableau blah
dans lequel nous accumulons diverses valeurs basées sur un champ clé. La forme de base est:
recdate date
rectime time
system varchar(20)
count integer
accum1 integer
accum2 integer
Il y a beaucoup plus accumulateurs que cela, mais ils sont tous de la même forme. La clé primaire est composée de recdate
, rectime
et system
.
Lorsque des valeurs sont collectées dans la table, le nombre de recdate/rectime/system
est incrémenté et les valeurs de cette clé sont ajoutées aux accumulateurs. Cela signifie que les moyennes peuvent être obtenues en utilisant accumN/count
.
Maintenant, nous avons aussi une vue sur la table spécifiée comme suit:
create view blah_v (
recdate, rectime, system, count,
accum1,
accum2
) as select distinct
recdate, rectime, system, count,
value (case when count > 0 then accum1/count end, 0),
value (case when count > 0 then accum2/count end, 0)
from blah;
En d'autres termes, la vue nous donne la valeur moyenne des accumulateurs plutôt que les sommes. Il s'assure également que nous n'obtenons pas de division par zéro dans les cas où le compte est zéro (ces enregistrements et existent et nous ne sommes pas autorisés à les supprimer, donc ne vous embêtez pas à me dire qu'ils sont des ordures - vous prêchez à la chorale).
Nous avons remarqué que la différence de temps entre la pratique:
select distinct recdate from XX
varie considérablement selon que l'on utilise la table ou la vue. Je parle de la différence étant 1 seconde pour la table et 27 secondes pour la vue (avec 100K lignes). Nous avons en fait retrouvé le select distinct
. Ce qui semble se passer, c'est que le SGBD charge actuellement toutes les lignes et les classe afin de supprimer les doublons. C'est juste, c'est ce que nous lui avons bêtement dit de faire. Mais je suis sûr que le fait que la vue inclue tous les composants de la clé primaire signifie qu'il est impossible d'avoir des doublons de toute façon. Nous avons validé le problème car, si nous créons une autre vue sans le distinct, il fonctionne à la même vitesse que la table sous-jacente. Je voulais juste confirmer ma compréhension qu'un select distinct
ne peut pas avoir de doublons s'il inclut tous les composants clés primaires. Si c'est le cas, nous pouvons simplement changer la vue de manière appropriée.