Join Method II

CHOOSING THE RIGHT JOIN METHOD

En muchas ocasiones dejamos al optimizador que decida que join utilizar. Sin embargo, en muchas ocasiones, ya sea por la mala elección del optimizador o por nuestros conocimientos de los datos nos permite una mejor toma de decisiones.

SORT-MERGE/HASH VERSUS NESTED LOOPS

Sort-merge join y hash join pueden ser considerados de la misma “familia” de joins (proporcionan un buen rendimiento bajo condiciones similares, mientras que los nested loops se adaptan a una categoría diferente de queries. Por lo tanto cuando determines que tipo de join usar, hay que plantearse si un nested loop es apropiada.

La decisión entre hash/sort-merge y nested loop debería estar basada en:

  • Necesidad de rendimiento vs necesidad de tiempo de respuesta. Nested Loop habitualmente ofrece mejor tiempo de respuesta, pero hash/sort-merge pueden ofrecer mejor rendimiento.
  • La proporción de tablas en el join. Un mayor subconjunto de filas procesadas puede ser más rápido con hash/sort-merge.
  • Disponibilidad de índices para soportar el join. Un nested loop es más efectivo cuando un índice puede ser usado en las tablas del join.
  • Memoria y CPU disponible para ordenaciones. Grandes ordenaciones pueden consumir una cantidad excesiva de recursos y puede ralentizar la ejecución.
  • Hash join podría conseguir grandes beneficios en ejecuciones paralelas y operaciones orientadas a partición. Aunque nested loop y sort-merge también pueden ser usadas en paralelización.

Table 1 Determining the Optimal Join Method

WHEN JOINING A TO B (IN THAT ORDER)  CONSIDER SORT-MERGE OR HASH JOIN?  CONSIDER NESTED LOOPS USING AN INDEX ON B?
Both A and B are small. Yes. Maybe, depending on the selectivity of the index and the size of the outer table.
Only selecting a small subset of rows from B (and B has an index). No. Performing a table scan of B will be cost-inefficient. Yes. The index will reduce the number of IOs on B.
Want the first row as quickly as possible. No. The first row won’t bereturned until both A and B are scanned, sorted, and merged or until the hash table has been built. Yes. Rows can be returned as soon as they are fetched using the index.
Want to get all rows as quickly as possible. Maybe. Nested loops might still get all rows before sort-merge or hash join if other conditions apply. Maybe. Nested loops might still get all rows before sort merge if other conditions apply.
Doing a full table scan of A and want to use parallel query. Yes. Yes. Nested loops can be resolved in parallel if the outer (first) table in the join is retrieved via a full table scan.
Memory is limited, especially PGA memory. Maybe not. Large sorts can have significant overhead, especially if memory for sorts is limited. Hash joins can also require more memory than nested loops. Yes. The nested loops join avoids sorting and is, therefore, less affected by memory limitations.

 SORT-MERGE VERSUS HASH JOINS
Sort-merge está disponible desde versiones antiguas de Oracle, mientras que el hash join es más reciente. Hash join puede ser empleado en muchos, pero no todos los caso donde puede ser empleado el sort-merge. Cuando ambos son directamente comparados, el hash join tiende a un mejor rendimiento que un sort-merge join.

Sin embargo, sort-merge join tiene una más amplia aplicabilidad. Hash join puede ser ejecutado sólo cuando la condición join es una condición de igualdad, y los sort-merge pueden ser utilizados para resolver condiciones de no igualdad.

El sort-merge requiere más memoria y para ejecutar eficientemente y más CPU para durante las ordenaciones.

Aunque el hash join habitualmente tiene un rendimiento superior que el sort-merge, si los datos de entrada ya están ordenados, las operaciones de ordenación serán menos costosas y el sort-merge será más efectivo.

Referencias: Oracle Performance Survival Guide (Guy Harrison)

Notas: La Table 1 he preferido no traducirla, ya que los conceptos pueden ser más sencillos de entender.

One Comments

  • Ricardo Calderón

    03/05/2013

    Hola Moises, gracias por la explicación!

    Tengo dos pequeñas dudas relacionadas con los tipos de join. Cuando generó reportes AWR , en algunas ocasiones me aparecen en el ‘Top 5 Timed Events’ los siguientes eventos: ‘db file sequential read’, el cual según la documentación de Oracle utiliza lecturas ‘no multibloque’, signiifica que necesariamente la instancia tiene un alto consumo de recursos por accesos indexados y ‘nested joins’?.

    De la misma forma me aparece el evento ‘db file scattered read’, el cual según la documentación es generado por lecturas ‘multibloque’. Esto necesariamente significa que la instancia se encuentra realizando ‘full scans’ y ‘hash joins’ ?

    Existe alguna información parecida a la tabla 1 que nos muestras, donde nos indique que tipo de memoria, pga o sga ocupa cada tipo de join? y que nos ayude a dimensionar estas dos memorias sin utlizar los ‘advisors ‘ de pga y sga?. Existe el parámetro ‘memory_target’ pero no le tengo mucha fé …

    saludos!

    Reply

Deja un comentario