varios solo repetidos registros rangos por elementos ejemplos consultas campos campo agrupar agrupadas agrupacion sql oracle plsql indexing

sql - solo - ¿Crear índices para agrupar por campos?



group by sql ejemplos (3)

¿Necesita crear un índice para campos de grupo por campos en una base de datos Oracle?

Por ejemplo:

select * from some_table where field_one is not null and field_two = ? group by field_three, field_four, field_five

Estaba probando los índices que creé para el anterior y el único índice relevante para esta consulta es un índice creado para field_two. Otros índices de campos únicos o compuestos creados en cualquiera de los otros campos no se usarán para la consulta anterior. ¿Esto suena correcto?


¿Necesita crear un índice para campos de grupo por campos en una base de datos Oracle?

No. No es necesario, en el sentido de que se ejecutará una consulta independientemente de si existen índices o no. Los índices se proporcionan para mejorar el rendimiento de la consulta.

Sin embargo, puede ayudar; pero dudaría en agregar un índice solo para ayudar a una consulta, sin pensar en el posible impacto del nuevo índice en la base de datos.

... el único índice relevante para esta consulta es un índice creado para field_two. Otros índices de campos únicos o compuestos creados en cualquiera de los otros campos no se usarán para la consulta anterior. ¿Esto suena correcto?

No siempre. A menudo, un GROUP BY requerirá que Oracle realice una clasificación (pero no siempre); y puede eliminar la operación de clasificación proporcionando un índice adecuado en la (s) columna (s) a clasificar.

Sin embargo, si realmente necesita preocuparse por el rendimiento de GROUP BY, es una pregunta importante para que piense.


No, esto puede ser incorrecto

Si tiene una tabla grande, Oracle puede preferir derivar los campos de los índices en lugar de la tabla, incluso si no hay un solo índice que cubra todos los valores.

En el último artículo en mi blog:

, hay una consulta en la que Oracle no utiliza la exploración de tabla completa, sino que une dos índices para obtener los valores de columna:

SELECT l.id, l.value FROM t_left l WHERE NOT EXISTS ( SELECT value FROM t_right r WHERE r.value = l.value )

El plan es:

SELECT STATEMENT HASH JOIN ANTI VIEW , 20090917_anti.index$_join$_001 HASH JOIN INDEX FAST FULL SCAN, 20090917_anti.PK_LEFT_ID INDEX FAST FULL SCAN, 20090917_anti.IX_LEFT_VALUE INDEX FAST FULL SCAN, 20090917_anti.IX_RIGHT_VALUE

Como puede ver, no hay TABLE SCAN en t_left aquí.

En cambio, Oracle toma los índices en id y value , los une en rowid y obtiene los pares (id, value) del resultado de la combinación.

Ahora, a tu consulta:

SELECT * FROM some_table WHERE field_one is not null and field_two = ? GROUP BY field_three, field_four, field_five

Primero, no compilará, ya que está seleccionando * de una tabla con una cláusula GROUP BY .

Necesita reemplazar * con expresiones basadas en las columnas de agrupación y los agregados de las columnas que no forman parte de la agrupación.

Probablemente se beneficie del siguiente índice:

CREATE INDEX ix_sometable_23451 ON some_table (field_two, field_three, field_four, field_five, field_one)

, ya que contendrá todo para el filtrado en field_two , ordenando field_three, field_four, field_five (útil para GROUP BY ) y asegurándose de que field_one NOT NULL .


Podría ser correcto, pero eso dependerá de la cantidad de datos que tenga. Normalmente crearía un índice para las columnas que estaba usando en un GROUP BY, pero en su caso el optimizador puede haber decidido que después de usar el índice field_two no se recuperarían suficientes datos para justificar el uso del otro índice para el GROUP POR.