Cuando se escribe la cláusula GROUP BY debemos tener en cuenta que el Firebird requiere que las columnas involucradas se encuentren ordenadas. Si no hay un índice que pueda usar entonces él se encargará de realizar el ordenamiento pero esa tarea puede demorar mucho tiempo en tablas grandes.

Listado 1.

SELECT
   VTC_IDECLI,
   VTC_FECHAX
FROM
   VENTASCAB
GROUP BY
   VTC_IDECLI,
   VTC_FECHAX

Aquí, como no hay un índice que el Firebird pueda usar entonces se ve obligado a crear un índice temporario, como podemos ver en el PLAN respectivo.

PLAN SORT ((VENTASCAB NATURAL))

La palabra SORT nos indica que el Firebird tuvo que ordenar a la tabla VENTASCAB. Ese ordenamiento puede demorar mucho si las filas son muy numerosas.

Listado 2.

SELECT
   VTC_CODSUC,
   VTC_IDECLI,
   VTC_FECHAX
FROM
   VENTASCAB
GROUP BY
   VTC_CODSUC,
   VTC_IDECLI,
   VTC_FECHAX

En este caso el PLAN que utilizó fue:

PLAN (VENTASCAB ORDER IDX_VENTASCAB3)

El cual nos indica que ordenó al resultado usando el índice de nombre IDX_VENTASCAB3

CUIDADO: Si en la cláusula WHERE tenemos un índice que se pueda usar entonces el Firebird lo utilizará aunque el orden de las columnas del SELECT no coincida con el orden de las columnas en el WHERE. Pero eso mismo no ocurre con la cláusula GROUP BY, porque aquí el orden sí importa. Ya hemos visto en un artículo anterior que los resultados obtenidos dependen del orden en que escribamos las columnas en la cláusula GROUP BY. Por lo tanto, para que un índice pueda ser utilizado deberán coincidir exactamente las columnas de ese índice con las columnas escritas en la cláusula GROUP BY. Ejemplificando: si en el GROUP BY del Listado 2. se hubiera escrito VTC_IDECLI, VTC_CODSUC, VTC_FECHAX, entonces el índice IDX_VENTASCAB3 no hubiera sido usado. Para usar a ese índice las columnas del GROUP BY deben escribirse sí o sí como VTC_CODSUC, VTC_IDECLI, VTC_FECHAX, porque ese es el orden de esas columnas en el índice. O sea, como el índice fue creado así:

Listado 3.

CREATE INDEX IDX_VENTASCAB3 ON VENTASCAB(VTC_CODSUC,VTC_IDECLI,VTC_FECHAX);

Solamente será usado si en la cláusula GROUP BY escribimos alguna de estas 3 alternativas:

VTC_CODSUC

VTC_CODSUC, VTC_IDECLI

VTC_CODSUC, VTC_IDECLI, VTC_FECHAX

Si en la cláusula GROUP BY escribimos cualquier otra combinación de columnas, el índice IDX_VENTASCAB3 no será usado.

Conclusión:

Cuando usamos la cláusula GROUP BY el Firebird sí o sí necesita que las columnas involucradas estén ordenadas. Si no existe un índice que pueda utilizar entonces él se encarga de ordenar a las columnas pero realizar esa tarea puede ser muy lento en tablas que tienen muchas filas. Por lo tanto en general nuestra mejor política es proveerle de ese índice.

Lo cual significa que cada vez que uses la cláusula GROUP BY debes preguntarte: ¿existe un índice para esas columnas?

Si no existe, debes pensar si es conveniente crearlo. Si aunque no existe un índice los resultados se obtienen muy rápido (porque son muy pocas las filas agrupadas) entonces no vale la pena crear ese índice.

Artículos relacionados:

Usando un PLAN

Algo más sobre PLAN

Entendiendo el contenido de un PLAN

Poniendo los JOIN en el orden correcto

Entendiendo la cláusula GROUP BY: agrupando datos

El índice del blog Firebird21

El foro del blog Firebird21

Anuncios