Estoy seguro que muchos de nosotros hemos tenido algun problema de mayor o menor escala con Bind Peeking introducido en Oracle 9i, especialmente los que migramos hace años de 8i a 9i.
Lo que hace bind peeking es si se utiliza las variables bind el primer parsing de un cursor (sentencia SQL) la variable se sustituye por el valor real y con ese valor se genera el plan de ejecucion, esto esta bien si todas las consultas usan ese valor que se ha generado el plan. Por ejemplo cuando consultas contra una tabla (con 500000 resgirtos) de facturas y quieres consultar las pendientes (estado), que podria representar solamente el 1% de la tabla, lo ideal es que el optimizador utilice un indice sobre el campo de estado, imaginense el primer parsing de la query es una consulta que en vez de consultar por el estado pendiente va por el estado cobrado, el plan de ejecucion seria un Full Table Scan sin embargo el resto de la gente que van a consultar por el estado pendiente seran las victimas de ese plan, una consulta que tarda millisegundos ppdria llegar a tardar hasta 30 segundos. (siempre partiendo con la idea de que la tabla tiene histogramas sobre el campo estado) Lo que es peor es que la consulta depende de los dias funciona bien ó mal y genera inestabilidades.
El bind peeking introduce de alguna manera alternativas e inteligencia que no existia en las versiones anteriores sin embargo se ha comprobado en numerosos casos que son los causantes de los problemas de rendimiento. De hecho aplicaciones como SAP, Siebel recomiendan deshabilitar bind peeking. En Oracle E-Business Suite me ha dado algun problemillas tambien.
Se ha visto que un plan de ejecucion no es optimo para todo los valores posibles de bind por lo tanto es necesario algun tipo de mecanismo mas inteligente que sea capaz de generar un plan de ejecucion por cada tipo de bind. En Oracle 11g se ha introducido el concepto de cursores inteligentes (Adapative Cursor Sharing) y esto ayudara a generar los posibles planes de ejecucion para los diferentes valores de bind. Con esto supongo que se pretende eliminar los problemas que hemos sufrido por el bind peeking. Pero habria que estudiarlo muy bien porque parece que necesita varios parsing de un cursor para llegar a un punto estable y tener todos los planes de ejecucion, y parece ser que es necesario Soft Parsing para que esto funcione (que pasaria con Packages de PL/SQL?).
En cuando pueda pondre un ejemplo demostrando la funcionalidad.
August 18, 2007 at 10:05 |
[...] select /* PURGE */ ename, dname from emp, dept where emp.deptno = dept.deptno and emp.deptno = :dept… [...]
August 31, 2007 at 21:23 |
[...] lscheng @ 5:04 pm Esta semana que he estado probando lo de Adaptive Cursor Sharing mencionado en Mas alla de Bind Peeking. Hace cosas raras, hay que estudiarlo mas a fondo pero funciona, ahora lo [...]
July 9, 2009 at 15:57 |
Más de Bind Peeking:
ORA-00600: internal error code, arguments: [kkslgbv0]
Después de analizar el .trc se ve cuando se intenta “alocar” esa variable y de ese nuevo parent cursor. ¿Qué pasa? que si a esto le añades que usas CURSOR_SHARING=SIMILAR, tienes la Library Cache un poco “petada” pues salta.
El kksl es para Shring Cursors, la G no se que será pero bv0 lo más probable es que sea Bind Variables. El caso es que en el momento de hacer un hard parse, saltaba.
En fin, solución fresca:
_optim_peek_user_binds=FALSE
y se acabó el bind peeking.
Lo único que me faltó averiguar (y por esto pregunto) es donde está dentro de la shared_pool ¿Si lo sabes, te lo agradecería? lo estuve intendo en x$ksmss, pero nop, no entendi donde está, porque existe el parámetro:
_xpl_peeked_binds_log_size
Su descripción es:
maximum bytes for logging peeked bind values for V$SQL_PLAN (0 = OFF)
Pero pienso que puede existir un valor que determine la cantidad de tamaño máximo para las binds. Pero, ¿Será que este valor solo tiene que ver con la cantidad de “parent cursor” que puedas tener? y bueno si es ASMM, hay un poco de lio.
Bueno te dejo mis inquietudes de justo ayer. Que leí este post intentando buscar posible comportamientos por deshabilitar el Bind Peeking con CURSOR_SHARING=SIMILAR. Y además aprovecho para mandarte un saludo.
John Ospino
PD: CURSOR_SHARING=SIMILAR un poco caca, he visto como una contulta tiene mas de 36000!!! chils cursors. Ojo, no es broma, más treinta y seis mil, select count(8) from v$sql where sql_id = ‘XXX’. Yde momento sin saber el porque crea otro child, ya que en v$sql_shared_cursor no sale nada.
July 9, 2009 at 17:18 |
Hola
En 10g que yo sepa si no ves ningun mismatch en v$sql_shared_cursor puede ser por los histogramas ó esta usando dynamic sampling la query.
–
LSC