sql >> Base de Datos >  >> RDS >> Oracle

¿Cuáles son las implicaciones de rendimiento de la cláusula IN de Oracle sin uniones?

Si las estadísticas en su tabla son precisas, debería ser muy poco probable que el optimizador elija hacer un escaneo de la tabla en lugar de usar el índice de clave principal cuando solo tiene 1000 elementos codificados en el WHERE cláusula. El mejor enfoque sería recopilar (o establecer) estadísticas precisas sobre sus objetos, ya que eso debería hacer que sucedan cosas buenas automáticamente en lugar de intentar hacer mucha gimnasia para evitar estadísticas incorrectas.

Si asumimos que las estadísticas son inexactas en la medida en que el optimizador creería que un escaneo de tabla sería más eficiente que usar el índice de clave principal, podría agregar potencialmente un DYNAMIC_SAMPLING pista que obligaría al optimizador a recopilar estadísticas más precisas antes de optimizar la declaración o una CARDINALITY Sugerencia para anular la estimación de cardinalidad predeterminada del optimizador. Ninguno de ellos requeriría saber nada sobre los índices disponibles, solo requeriría conocer el alias de la tabla (o el nombre si no hay un alias). DYNAMIC_SAMPLING sería el enfoque más seguro y sólido, pero agregaría tiempo al paso de análisis.

Si está creando una instrucción SQL con un número variable de parámetros codificados en un IN cláusula, es probable que esté creando problemas de rendimiento para usted mismo al inundar su grupo compartido con SQL no compartible y obligar a la base de datos a pasar mucho tiempo analizando cada variante por separado. Sería mucho más eficiente si creara una sola instrucción SQL compartible que pudiera analizarse una vez. Dependiendo de dónde esté su IN de donde provienen los valores de las cláusulas, que podría parecerse a

SELECT *
  FROM table_name
 WHERE primary_key IN (SELECT primary_key
                         FROM global_temporary_table);

o

SELECT *
  FROM table_name
 WHERE primary_key IN (SELECT primary_key
                         FROM TABLE( nested_table ));

o

SELECT *
  FROM table_name
 WHERE primary_key IN (SELECT primary_key
                         FROM some_other_source);

Si tuviera una sola instrucción SQL compartible, además de evitar el costo de volver a analizar constantemente la declaración, tendría varias opciones para forzar un plan particular que no implique modificar la declaración SQL. Las diferentes versiones de Oracle tienen diferentes opciones para la estabilidad del plan:hay esquemas almacenados , Gestión de planes SQL y perfiles de SQL entre otras tecnologías dependiendo de su versión. Puede usarlos para forzar planes particulares para declaraciones SQL particulares. Sin embargo, si continúa generando nuevas sentencias SQL que tienen que volver a analizarse, se vuelve muy difícil usar estas tecnologías.