2010-05-03 749 views
6

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.

Respuesta

3

Sí, no tiene sentido solicitar distinct resultados cuando se incluyen todos los elementos clave principales.

La restricción de clave primaria de la tabla ya impide duplicados en esas columnas, pero el DBMS aún procesará las tuplas para garantizar que sean distintas.

2

Si la vista se selecciona directamente de una sola tabla y un subconjunto de columnas seleccionadas es único en la tabla, se deduce que las filas seleccionadas serían únicas en valores y distinta es redundante.

4

En este caso, DISTINCT no le está haciendo ningún bien porque sus distintos campos ya están garantizados como únicos debido a la restricción PRIMARY KEY en la tabla subyacente.Usted puede tratar de volver a escribir la vista como:

create view blah_v ( 
    recdate, rectime, system, count, 
    accum1, 
    accum2 
) as select 
     recdate, rectime, system, count, 
     case when count > 0 then accum1/count else 0 end, 
     case when count > 0 then accum2/count else 0 end, 
     from blah; 

Compartir y disfrutar.

Cuestiones relacionadas