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

Oracle usa o ignora la columna indexada según el formato de to_date (literal)

Ok, lo intentaré, esto es principalmente una deducción de la información disponible:

¿Por qué Oracle elige un plan de ejecución diferente?

Parece que en su segunda consulta con el formato de fecha inusual, el optimizador no tiene idea de cuál es el valor de la fecha resultante. Verá el predicado de filtro:

1 - filter(TO_DATE('20140610 ','yyyymmdd ')<=TO_DATE(' 2014-06-10 23:59:59', 'syyyy-mm-dd hh24:mi:ss'))

¡Lo que significa que el optimizador ni siquiera está seguro de que la primera fecha sea más pequeña que la segunda! Eso significa que el optimizador no tiene idea de la cantidad de filas devueltas y solo usará un plan genérico sin tener en cuenta estadísticas específicas. Sería lo mismo si tuviera una función definida por el usuario xyt() que devolvería una fecha para el rango. El optimizador no tiene forma de saber qué valor de fecha resultará:esto significa que obtiene un plan general para todos los propósitos, que debería ser bastante decente para cualquier rango de fechas especificado.

En el primer y tercer caso, el optimizador parece comprender la fecha directamente y puede adivinar el número de filas que se encuentran en el intervalo de fechas mediante el uso de estadísticas. Entonces, mientras que la segunda Consulta fue al Optimizador como BETWEEN X AND 3 esta Consulta es como BETWEEN 1 AND 3 ¡Así que optimiza el plan de consulta para el número previsto de filas devueltas!

Lo extraño parece ser que el optimizador de consultas tiene tales problemas con un formato de fecha extraño, podría archivarse como un error/solicitud de mejora...

Pero un punto importante:

  1. Un escaneo completo de la tabla no tiene por qué ser un mal plan... ¡Además, usar un índice no siempre es más rápido!
  2. El costo en el plan de consulta no está directamente relacionado con el tiempo de ejecución real o el rendimiento:es una medida interna para comparar diferentes planes para la MISMA CONSULTA (por lo que no puede comparar el costo de diferentes consultas como sus consultas 1 ,2 y 3)

Básicamente, si devuelve una gran cantidad de filas de una tabla, un escaneo completo de la tabla sin acceso al índice en muchos casos será mucho más rápido, ¡especialmente cuando se opera en ciertas particiones! - El escaneo de la tabla solo accederá a la partición para el rango de fechas coincidente, por lo que solo para la fecha en cuestión y devuelve todas las filas de esta partición. Esto es mucho más rápido que consultar el índice para cada fila individual y luego extraer la fila por acceso de índice... Intente perfilar las consultas:el escaneo completo de la tabla en la partición debe ser 3 veces más rápido con mucho menos IO