Recientemente descubrimos un problema de rendimiento con uno de nuestros sistemas y creo que tengo la solución, pero no estoy seguro de que mi comprensión sea correcta.¿Es correcto mi entendimiento de "seleccionar distinto"?
En la forma más simple, tenemos una tabla blah
en la que acumulamos varios valores basados en un campo clave. La forma básica es:
recdate date
rectime time
system varchar(20)
count integer
accum1 integer
accum2 integer
Hay acumuladores mucho más que eso, pero todos son de la misma forma. La clave principal se compone de recdate
, rectime
y system
.
A medida que se recopilan los valores en la tabla, el recuento de un recdate/rectime/system
dado se incrementa y los valores de esa clave se agregan a los acumuladores. Eso significa que los promedios se pueden obtener usando accumN/count
.
Ahora también tenemos una vista sobre la mesa especificada de la siguiente manera:
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 otras palabras, la vista nos da el valor medio de los acumuladores en lugar de las sumas. También se asegura de que no obtengamos una división por cero en los casos donde el conteo es cero (estos registros hacen existen y no podemos eliminarlos así que no se moleste en decirme que son basura, estás predicando al coro).
Nos hemos dado cuenta de que la diferencia de tiempo entre hacer:
select distinct recdate from XX
varía en gran medida dependiendo de si usamos la tabla o la vista. Estoy hablando de la diferencia de 1 segundo para la tabla y 27 segundos para la vista (con 100K filas).
Lo hemos rastreado hasta el select distinct
. Lo que parece estar sucediendo es que el DBMS está cargando todas las filas y clasificándolas para eliminar duplicados. Eso es justo, es lo que estúpidamente le dijimos que hiciera.
Pero estoy bastante seguro de que el hecho de que la vista incluya todos los componentes de la clave principal significa que de todos modos es imposible tener duplicados. Validamos el problema ya que, si creamos otra vista sin la diferencia, se realiza a la misma velocidad que la tabla subyacente.
Solo quería confirmar mi comprensión de que un select distinct
no puede tener duplicados si incluye todos los componentes de la clave principal. Si eso es así, entonces podemos simplemente cambiar la vista de manera apropiada.