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

¿Por qué la verificación de nulo ralentiza esta consulta?

La única forma en que puedo pensar para obtener ese tipo de diferencia en la velocidad de ejecución sería (a) tener un índice en field4 y (b) tener mucho mucho de bloques de datos vacíos; posiblemente de una marca de agua alta establecida muy alta por cargas de ruta directa repetidas.

La primera consulta aún usaría el índice y funcionaría como se esperaba. Pero como los valores nulos no están indexados, el índice no se puede usar para verificar que el or field4 is null condición, por lo que volvería a un escaneo completo de la tabla.

Eso en sí mismo no debería ser un problema aquí, ya que un escaneo completo de la tabla de 7000 filas no debería llevar mucho tiempo. Pero ya que es tardando tanto, algo más está pasando. Un escaneo completo de la tabla debe examinar cada bloque de datos asignado a la tabla para ver si contienen filas, y el tiempo que lleva sugiere que hay muchos más bloques de los que necesita para contener 7000 filas, incluso con almacenamiento CLOB en línea.

La forma más sencilla de obtener muchos bloques de datos vacíos es tener muchos datos y luego eliminar la mayor parte. Pero creo que dijiste en un comentario ahora eliminado sobre una pregunta anterior que el rendimiento solía estar bien y empeoró. Eso puede suceder si realiza inserciones de ruta directa , particularmente si 'actualiza' los datos eliminándolos y luego insertando nuevos datos en el modo de ruta directa. Podría estar haciendo eso con inserciones que tienen el /*+ append */ insinuación; o en paralelo; o mediante SQL*Loader. Cada vez que lo hiciera, la marca de agua máxima se movería, ya que los viejos bloques vacíos no se reutilizarían; y cada vez que el rendimiento de la consulta que verifica los valores nulos se degradaría un poco. Después de muchas iteraciones, eso realmente comenzaría a sumar.

Puede consultar el diccionario de datos para ver cuánto espacio se asigna a su tabla (user_segments etc.), y compáralo con el tamaño de los datos que crees que realmente tienes. Puede restablecer el HWM reconstruyendo la tabla, por ejemplo, haciendo:

alter table mytable move;

(¡preferiblemente en una ventana de mantenimiento!)

Como demostración, ejecuté un ciclo para insertar y eliminar 7000 filas de ruta directa más de cien veces, y luego ejecuté ambas consultas. El primero tardó 0,06 segundos (gran parte de los cuales son gastos generales de SQL Devleoper); el segundo tomó 1.260. (También ejecuté Gordon's, que obtuvo un tiempo similar, ya que todavía tiene que hacer un FTS). Con más iteraciones, la diferencia sería aún más marcada, pero me quedé sin espacio... Luego hice un alter table move y volvió a ejecutar su segunda consulta, que tardó 0,05 segundos.