Hoy ha salido a la venta el libro «Optimización SQL en Oracle» en formato Kindle.
Aun hay esperar a que Amazon vincule la edición impresa y la electrónica (dicen que sobre unas 48 horas), sobre todo porque el libro está en Amazon Matchbook, que permite que quien ha comprado la edición impresa pueda descargarse el libro en Kindle gratis, aunque creo que esta opción sólo está disponible en amazon.com por el momento.
¿Por qué ha tardado tanto en salir la edición Kindle?
Para empezar, porque es un libro concebido para un tamaño concreto. Está lleno de líneas de código y outputs de pantalla (en ocasiones con anchos de línea de 140 o 160 caracteres) para que los planes de ejecución puedan leerse correctamente. El libro impreso tiene un tamaño de ancho y alto de 9.6 pulgadas x 6.7 pulgadas (24,6cm x 17cm) y otras pruebas de impresión a formatos más reducidos perdían legibilidad. ¿Has visto alguna vez un plan de ejecución con explain plan en tu iPhone? Complicado.
¿Por qué una edición en Kindle?
Personalmente, pienso que la edición impresa es de lujo. La calidad de impresión es ideal, los contenidos están indexados por palabras al final del libro y, por lo que nos han comentado los lectores, vale la pena tenerlo impreso y leerlo de principio a fin. La maquetación de los contenidos y las imágenes están ajustadas al tamaño del papel. No obstante, tenerlo en papel implica en ocasiones unos gastos de envío (en ciertos países con fuertes cargos de aduana) y unos tiempos de espera considerables.
Con esta edición, el libro puede estar disponible inmediatamente en los dispositivos digitales, y gratis para quien haya adquirido el libro en Amazon (que imagino que serán los usuarios de Kindle), con actualizaciones de contenido que las impresiones registradas con ISBN en papel no permiten, con todas las ventajas que la lectura electrónica ofrece como búsqueda de palabras, diccionario, lectura práctica, lectura en el PC con copy/paste directamente del código del libro, etc.
¿Cómo se han resuelto estos aspectos de visualización?
Para empezar, el libro incluye embebida una fuente gratuita Courier Prime para que el código y el resultado se vea lo más parecido al libro impreso. La mayoría de problemas de se resuelven reduciendo la fuente o usando la visualización horizontal. ADVERTENCIA! No obstante, en ciertos dispositivos como iPhone o Kindle2 (el más pequeño), algunos planes de ejecución más complejos se pueden leen con cierta dificultad.
En estos casos, lo más recomendable es descargarse el código SQL de ejemplo de la web y seguir la lectura practicando con los ejemplos sobre la base de datos.
Hace unos días adquirí su libro a través de Amazon, por el cual lo felicito ya que me parece de gran valor didáctico.
Al leer el primero de sus capítulos me ha entrado una duda. A lo largo de la primera parte, al hablar de las Bind Variables hace hincapié de que en caso de tener el parámetro CURSOR_SHARING configurado a SIMILAR o FORCE puede ser un problema en versiones menores a 11g ya que no se realiza un Adaptative Cursor Sharing y por tanto el optimizador puede llegar a tomar decisiones que sean erróneas para posteriores sentencias. Mi duda es, si en caso de estar el parámetro configurado a EXACT no pasará los mismo si la aplicación o cliente trabaja con Variables Bind.
Muchas gracias de antemano y felicidades de nuevo por su libro.
Hola Javier
Gracias a ti por comprar el libro y ser un lector interactivo! Me alegra mucho que te esté resultando interesante lo que vas leyendo!
Sí, tu enfoque es correcto. Si todo el código usara bind variables el comportamiento del optimizador en EXACT sería igual que en FORCE. La cuestión es que no son parámetros «buenos» o «malos», sino formas de funcionar más eficientes o menos según todo el contexto.
En realidad no quiero decir que si el CURSOR_SHARING está en similar o force sea algo malo, sino que es importante tener en cuenta como se comporta el optimizador y que forma tiene el código SQL que ejecutan las aplicaciones.
Definitivamente el tema del uso de bind variables implica tener varias cosas presentes:
1.- lo ideal sería que los programadores tengan en cuenta como funciona el optimizador para decidir que valores expresan de forma literal y cuales mediante una bind variable. Si se filtra por un elemento «variable» (nombre cliente) y por un elemento a interpretar de forma «literal» (factura impagada), no sería preciso alterar la forma natural de trabajar del optimizador y en valor EXACT se tomaría ventaja de todo: histogramas para los literales, y bind variables fijadas (bind variable peeking) que puedan adaptarse (Adaptive Cursor Sharing) si las ejecuciones no tardan un tiempo similar al esperado.
2.- si no es así, y todo esta expresado con literales el abuso de los hard parses para código «similar» nos dará un cuello de botella en CPU compilando fases de parse completas para sentencias en las que sólo cambia un campo NIF? El coste en tiempo de un hard parse (no de uno, sino de mil o diez mil usuarios concurrentes) es mucho mayor que un soft parse (1.000 o 10.000 soft parse) y puede ser la diferencia entre tener el motor colapsado y esperas por CPU o que el sistema vaya fluido.
3.- El hecho de que todo se exprese con variables tampoco es bueno… fíjate en el ejemplo con la tabla EMP2 (página 46 del libro impreso) en el ejemplo de como funciona el Adaptive Cursor Sharing: el primer plan de fija (usando índice) y en la segunda ejecución sobre el dept 20 (lo mejor sería un full scan) vuelve a usar ese plan ineficiente, pero el optimizador se da cuenta una vez ha tardado un tiempo desproporcionado y fija el plan para revisarse marcando esa versión como «is_bind_aware». Si la siguiente ejecución fuera por un valor muy restrictivo el plan adaptado volvería a ser usando índice y otra ejecución sobre 40.000 o 50.000 filas se volverá a ejecutar con un plan ineficiente usando índices que no debe. Imagina sentencias con un gran número de variables, ¿cuál de ellas ha sido la causante del mayor coste? Nada garantiza que la siguiente vaya a determinar un plan eficiente… al fin y al cabo, el ACS es un intento de mitigar el impacto de planes fijados que no valen para todos los casos (facturas pagadas o impagadas, etc).
Por ese motivo, en el libro contamos la evolución histórica del funcionamiento del optimizador y de las mejoras que se han ido introduciendo en las sucesivas versiones. También con la intención de que el usuario no se vuelva loco viendo varios planes para diferentes variables en una misma sentencia y, lo más importante, no pensar en «este parámetro a este valor funciona mal» sino en toda una maquinaria configurable a diferentes modos de optimizar e interpretar el SQL y, luego, adaptarlo a cada escenario.
¿Cómo es el código SQL la aplicación? ¿No tiene ninguna bind variable? ¿Sólo usa bind variables? ¿Todos los literales se comportan como variables por una transformación del CURSOR_SHARING? ¿Se usan histogramas? ¿Son útiles?
Salta en el libro a la página 401 dónde se cuenta la hint /*+CURSOR_SHARING_EXACT */ es otra herramienta que puede ir bien si tu código está bien implementado en una bbdd definida a force o similar y estas sufriendo un comportamiento no deseado.
En la página 65 hay otra reflexión sobre el uso de bind variables con histogramas… Y en la página 145 un ejemplo de confusión del optimizador en la selectividad de filas y de como /*+DYNAMIC_SAMPLING */ puede ser útil para ayudar al optimizador a evitar confusiones de ese tipo.
Espero que el libro te resulte interesante! Puedes contactar conmigo para cualquier cosa que necesites! Un saludo