Wir haben vor kurzem ein Performance-Problem mit einem unserer Systeme entdeckt und ich denke, ich habe die Lösung, aber ich bin mir nicht sicher, ob mein Verständnis korrekt ist.Ist mein Verständnis von "Select distinct" korrekt?
In der einfachsten Form haben wir eine Tabelle blah
, in der wir verschiedene Werte basierend auf einem Schlüsselfeld ansammeln. Das Grundformular ist:
recdate date
rectime time
system varchar(20)
count integer
accum1 integer
accum2 integer
Es gibt viel mehr Akkumulatoren als das, aber sie sind alle von der gleichen Form. Der Primärschlüssel besteht aus recdate
, rectime
und system
.
Während die Werte in der Tabelle gesammelt werden, wird der Zähler für eine gegebene recdate/rectime/system
inkrementiert und die Werte für diesen Schlüssel werden den Akkumulatoren hinzugefügt. Das bedeutet, dass die Durchschnittswerte erhalten werden können, indem accumN/count
verwendet wird.
Jetzt haben wir auch einen Blick auf diese Tabelle wie folgt angegeben:
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;
Mit anderen Worten, gibt die Ansicht uns den Durchschnittswert der Akkumulatoren eher als die Summen. Es stellt auch sicher, dass wir keine Division durch Null in den Fällen erhalten, in denen die Zählung Null ist (diese Datensätze existieren und wir dürfen sie nicht entfernen, also mach dir keine Sorgen, mir zu sagen, dass sie Quatsch sind - du predigst dem Chor).
Wir haben festgestellt haben, dass die Zeitdifferenz zwischen Tun:
select distinct recdate from XX
stark in Abhängigkeit davon variiert, ob wir die Tabelle oder die Ansicht verwenden. Ich spreche über den Unterschied, 1 Sekunde für die Tabelle und 27 Sekunden für die Ansicht (mit 100 K Zeilen).
Wir haben es tatsächlich zurück auf die select distinct
verfolgt. Offensichtlich lädt das DBMS alle Zeilen und sortiert sie, um Duplikate zu entfernen. Das ist ehrlich gesagt, es ist das, was wir dumm gesagt haben.
Aber ich bin ziemlich sicher, die Tatsache, dass die Ansicht jede Komponente des Primärschlüssels enthält, bedeutet, dass es unmöglich ist, Duplikate sowieso zu haben. Wir haben das Problem validiert, da es, wenn wir eine andere Ansicht ohne distinct erstellen, mit der gleichen Geschwindigkeit wie die zugrunde liegende Tabelle arbeitet.
Ich wollte nur bestätigen, dass ein select distinct
keine Duplikate haben kann, wenn es alle Primärschlüsselkomponenten enthält. Wenn das so ist, können wir einfach die Ansicht entsprechend ändern.