Optimización de Consultas SQL con Planes de Ejecución y Índices
Resumen
¿Cómo se puede entender un plan de ejecución en SQL?
Un plan de ejecución es una representación gráfica detallada de cómo la base de datos SQL procesa una consulta. Comprender este plan es crucial para optimizar las consultas y asegurarse de que los recursos del sistema se utilicen de manera eficiente. Al estudiar los componentes gráficos del plan, se puede mejorar el rendimiento de las consultas, especialmente en bases de datos de gran tamaño.
Los planes de ejecución indican cómo se unen las tablas, el costo asociado a cada operación y sugieren posibles índices que podrían mejorar la consulta. Este conocimiento permite tomar decisiones informadas para optimizar la base de datos.
¿Cómo interpretar las sugerencias de índices?
Cuando una consulta SQL se ejecuta, el sistema puede sugerir la creación de índices para mejorar su rendimiento. Un índice es como un mapa que facilita encontrar rápidamente los datos necesarios. Por ejemplo, en una consulta con un JOIN de tres tablas, el sistema podría indicar que agregar un índice a ciertas columnas mejoraría la eficiencia.
Creación de un índice sugerido
Supongamos que SQL recomienda un índice. Podemos proceder a crearlo de la siguiente manera:
Este índice nos ayudará a mejorar la velocidad de las consultas, reduciendo costos de CPU y tiempos de lectura/escritura en el disco.
Analizando el impacto de un índice
Después de crear el índice, observa cómo el costo del plan de ejecución disminuye significativamente. Por ejemplo, en un caso práctico, un costo inicial de ejecución era del 43%, y tras optimizar el índice, se redujo a un nivel insignificante, lo que indica un uso más eficiente de los recursos. En situaciones más grandes, como en consultas que involucran múltiples tablas con millones de registros, esta optimización es crítica.
¿Qué es un Índice Seek?
El término Index Seek se refiere a la acción de buscar datos específicos en un índice, lo que es más eficiente que escanear toda la tabla. Esto es particularmente útil cuando la consulta accede a un número reducido de filas dentro de un gran conjunto de datos.
Uso correcto de Index Seek
En un ejemplo práctico, un Index Seek fue utilizado eficazmente en una consulta donde había un JOIN en la misma tabla. Aquí, SQL realizó 132 búsquedas específicas, minimizando la duplicidad de esfuerzos en comparación con si se utilizara un Table Scan, que es mucho menos eficiente.
Para optimizar un Index Seek, asegúrate de que todas las columnas necesarias aparezcan en el índice. Si una columna utilizada en la consulta no está en el índice, puedes agregarla como parte de las columnas incluidas.
¿Por qué es importante habilitar las estadísticas?
Las estadísticas son claves para evaluar y optimizar el rendimiento de consultas SQL. Proporcionan datos sobre cuántas "lecturas lógicas" se realizaron y el impacto de cada consulta en el sistema. Esto resulta vital incluso cuando los planes de ejecución y los índices parecen correctos, ya que una carga lógica alta puede indicar la necesidad de ajustes adicionales.
Recomendaciones para el uso de estadísticas
Monitorea las lecturas lógicas: Asegúrate de que sean lo más bajas posible para aumentar la eficiencia.
Compara estadísticas antes y después de un ajuste: Permite validar la efectividad de las optimizaciones realizadas.
Utiliza las estadísticas para identificar cuellos de botella: Esto es esencial para diagnosticar problemas ocultos en las consultas.
Recursos adicionales para el estudio de planes de ejecución
Para una comprensión más profunda de los planos de ejecución, se recomienda consultar manuales especializados que detallen cada ícono y su función. Este conocimiento adicional capacita a los desarrolladores para realizar ajustes específicos y mejorar el rendimiento a lo largo de la vida útil de una base de datos.
Con estos conocimientos, avanzarás en la optimización y gestión eficiente de tus bases de datos SQL, permitiéndote realizar consultas más rápidas y eficaces. ¡Continúa explorando y aprendiendo para dominar el arte de la optimización de consultas!
La explicación del video es muy vaga, ademas que no explica el por que lo hace, solo que hace y como lo hace.
No analiza la consulta, solo resuelve el problema.
siento que volví a la universidad y veía a mis compañeros exponer un tema que "estudiaron" la noche anterior mientras estaban bebiendo
me siento muy identificado con tu descripción XD
Antes de esta clase, tenìa el conocimiento que al agregar columnas en el ìndice era a las que yo utilizaba para filtrar en mi query (where). Pero ahoras sè que es a la columna que deseo mostrar (Select)
Me parece interesante como llegaste a esa conclusión, por que en el video no dicen nada de eso.
Tienes razón, pero la explicación del video es muy vaga, ademas que no explica el por que lo hace, solo que hace y como lo hace.
De hecho si lo menciona, en el 6:48
Cuál es la diferencia entre NonClustered y Clustered?
El indice clustered, ordena tu tabla fisica de la manera en la que tengas definido el indice. El non clustered, solamente guarda apuntadores de donde están tus datos.
Analizar este tipo de consultas es una tarea compleja, es muy importante conocer el fin de la consulta y así poder optimizarla. Importante utilizar las mejores prácticas y una de esas es no utilizar asterisco * en él SELECT.
Creo que tuvo que haber mas videos de este tema. Parece muy interesante, pero no profundiza en como entender los planes de ejecucion.
Por lo que entiendo, debería construir índices que suplan las consultas recurrentes que realizo en mi base de datos. al ser subconsultas en alguna parte deben quedar almacenadas, en una base de datos muy grande, si se tienen muchos índices podría ocupar mucho espacio al final resultar ser más un problema que una solución.
Así es por lo general en la práctica no se recomiendan más de un par de índices por tabla y esto dependiendo de las consultas recurrentes.
La segunda query no está en el archivo :/
Cuando estoy diseñando la base de datos, la forma de saber que indices crear y configurar, es apartir del query? o hay algo que me diga como hacerlo de forma apriori?
Normalmente al momento de diseñar la BD son los mismos atributos de la entidad lo que te da la pauta para saber que propiedad puede ser un índice, ya que es necesario que el campo sea único para cada elemento. Por ejemplo si estas haciendo una BD que guarda datos de personas, un campo que te puede servir de índice o llave primaria en este caso sería el numero de registro de población (CURP) en México, ya que es único para cada persona. En caso que la entidad no posea un atributo de éste tipo lo normal es que tu generes la funcionalidad para generar un ID único, puede ser dejando que el mismo SMBD lo genere (regularmente es la propiedad autoincrement) o generar un uuid con alguna librería programáticamente.
también si vas a estar haciendo consultas sobre un campo en especifico, este puede ser un buen candidato a tener un indice.
Veo en los comentarios que todos tenemos mucha confusión en las explicaciones de esta clase y creo que es porque han cambiado el orden de las clases. Esta clase 7 Analizar las consultas para crear índices va después de la próxima clase 8 ¿Cómo nos pueden ayudar los índices?.
Si os fijáis en el minuto 6:25 el profe dice: "Como ya habíamos hecho..." y realmente lo hace en la próxima clase.
se ve complejo, deberia extenderse la explicación.
por mi lado voy a ir a ver post y documentación en internet
Puedo hacer tantos índices como yo necesite sobre una misma tabla? cómo sabe SQL cual índice usar si hubiera varios en una misma tabla? Si es una tabla de transacción la cual se modifica, borra e inserta todo el tiempo no pasa nada con los índices????
Si, puedes tener tantos indices como tu quieras, pero debes tener cuidado de no sobreindexar la tabla. Es mejor tener varios indices adecuados que muchos que no sirvan. Cada indicé hará mas pesada tu tabla, debido a que SQL tiene que guardar los datos del indice. Hay un componente interno de SQL que se llama Query Optimizer y se encarga de elegir el mejor indice para tu consulta. La mayoría de las veces lo hace correctamente, pero tiene sus excepciones. Cada inserción, borrado o modificación de la tabla, además de afectar la tabla fisica, también tiene que afectar los indices, es por eso que poner tantos no necesariamente es optimo. Además de que eso genera fragmentación en los indices y despues tienes que ejecutar el plan te mtto.
Como bien dice ElTalJL puedes tener tantos indices como quieras, pero eso no quiere decir que eso te vaya a beneficiar. Si viste en la clase, indico que hay que analizar cada caso por aparte, ver cuales indices nos benefician y cuales no. Con los planes de ejcución podemos ver cuales indices se utilizan y que carga le crea a la base de datos. En lo que mencionas para tablas "transaccion", pues claro que el indice es muy importante, depende de que condiciones tengas en el "where" y ahi se utilizará algun indice, no solo el de PK.
Cuando ejecuto la consulta del archivo descargado, ya no me sale la advertencia de "Missing Index", seguramente es porque en las ejecuciones previas hicimos la optimización recomendada en el video previo, y se pierde un poco el seguimiento en el ambiente de prueba local. Sería bueno incluir en el script la desoptimización anterior aplicada, como una especie de deshacer.
Eliminar indice "IX_prueba" en la tabla Warehouse.StockItemTransactions en el explorador de Objetos
Gracias, nperez. Es correcto, ya siguiendo el curso queda claro dónde y cómo eliminar.
Lo que puedo entender es identificar la columna que más se consulta y sobre éstas agregarlas al índice.
Depende también el tipo de datos, lo ideal que yo uso en la práctica son índices sobre tipos numéricos, fecha o cualquiera que se pueda ordenar. Sin embargo es muy común que en algunas empresas ordenen índices sobre tipos de datos nvarchar y esto realmente casi no tiene impacto por su naturaleza de cadena. Saludos.
¿Es posible evitar consultas dobles en SQL?
Sí, es totalmente posible y es una de las optimizaciones más importantes que puedes hacer. Las consultas dobles ocurren cuando SQL encuentra los registros usando un índice (un Index Seek), pero se da cuenta de que le faltan columnas solicitadas en el SELECT. Para compensarlo, hace una segunda visita a la tabla original por cada registro encontrado. Si tu consulta devuelve 130 filas, hará 130 viajes adicionales. Para evitar este comportamiento ineficiente, debes modificar tu índice existente y agregar las columnas faltantes como columnas incluidas. Al hacer esto, el índice almacena una copia de esos datos específicos. Cuando ejecutes tu consulta nuevamente, SQL encontrará absolutamente todo lo que necesita en la primera pasada por el índice, eliminando el doble consumo de memoria y acelerando el resultado de forma espectacular.
Crear índices en una tabla mejora el rendimiento de las consultas, pero no es recomendable indexar cada columna. Los índices ocupan espacio y ralentizan las operaciones de escritura (INSERT, UPDATE, DELETE) porque deben actualizarse cada vez que se modifica la tabla. Idealmente, se deben crear índices en columnas que se usan con frecuencia en filtros, joins o como claves foráneas. Esto optimiza el rendimiento sin incurrir en los costos de mantenimiento de índices innecesarios.
En una consulta SQL, si tienes más columnas que necesitas mostrar, es recomendable incluirlas en el índice si estas columnas son frecuentemente consultadas. Esto es porque un índice puede ayudar a reducir el tiempo de consulta al permitir que SQL Server acceda a los datos de manera más eficiente. Sin embargo, añadir muchas columnas a un índice puede incrementar el tamaño del índice y afectar el rendimiento en operaciones de escritura. Por lo tanto, es importante balancear entre la eficiencia de lectura y los costos de mantenimiento del índice.
En mi trabajo utilizamos DB2, ¿qué herramienta me recomiendan para ver y hacer estos análisis de rendimiento en mis consultas?
Hola, esa base de datos no la domino, en este caso es mejor que busques aqui un curso sobre ese tema o en google o youtube vas a encontrar la información.
xq poner en CREATE NONCLUSTERED INDEX [IX_borrar01] a que hace referencia ?
Una consulta, en el plan de ejecucion hay un texto Query 1: Query cost (relative to the batch) :100%.
Este porcentaje es el mismo con el cambio(trigger) y sin el cambio ¿no deberia ser menor si es mas optimo el query?