Cuando tiene una consulta o procedimiento almacenado que necesita ajuste de rendimiento, ¿cuáles son algunas de las primeras cosas que intenta?
sql
sql-server
database
performance
Terrapin
fuente
fuente
Respuestas:
Aquí está la lista práctica de cosas que siempre le doy a alguien que me pregunta sobre la optimización.
Utilizamos principalmente Sybase, pero la mayoría de los consejos se aplicarán en todos los ámbitos.
SQL Server, por ejemplo, viene con una gran cantidad de bits de supervisión / ajuste del rendimiento, pero si no tiene nada de eso (y tal vez incluso si lo tiene), consideraría lo siguiente ...
El 99% de los problemas que he visto son causados por poner demasiadas tablas en una unión . La solución para esto es hacer la mitad de la unión (con algunas de las tablas) y almacenar en caché los resultados en una tabla temporal. Luego haga el resto de la consulta uniéndose en esa tabla temporal.
Lista de verificación de optimización de consultas
#temp
Las tablas pueden funcionar mucho mejor que las@table
variables con grandes volúmenes (miles de filas).fuente
fuente
Ligeramente fuera de tema, pero si tiene control sobre estos temas ...
Alto nivel y alto impacto.
fuente
CREATE INDEX
Asegúrese de que haya índices disponibles para sus cláusulas
WHERE
yJOIN
. Esto acelerará el acceso a los datos en gran medida.Si su entorno es un data mart o un almacén, los índices deberían abundar para casi cualquier consulta concebible.
En un entorno transaccional , el número de índices debería ser menor y sus definiciones más estratégicas para que el mantenimiento del índice no reduzca los recursos. (El mantenimiento del índice es cuando las hojas de un índice deben cambiarse para reflejar un cambio en la tabla subyacente, como con
INSERT, UPDATE,
yDELETE
operaciones).Además, tenga en cuenta el orden de los campos en el índice: cuanto más selectivo (mayor cardinalidad) sea un campo, más temprano debería aparecer en el índice. Por ejemplo, supongamos que está buscando automóviles usados:
El precio generalmente tiene mayor cardinalidad. Puede haber solo unas pocas docenas de colores disponibles, pero posiblemente miles de precios diferentes.
De estas opciones de índice,
idx01
proporciona la ruta más rápida para satisfacer la consulta:Esto se debe a que menos automóviles satisfarán el precio que la elección del color, lo que le da al motor de consulta muchos menos datos para analizar.
Se sabe que tengo dos índices muy similares que difieren solo en el orden de los campos para acelerar las consultas (nombre, apellido) en uno y (apellido, nombre) en el otro.
fuente
Un truco que aprendí recientemente es que SQL Server puede actualizar variables locales, así como campos, en una declaración de actualización.
O la versión más legible:
He usado esto para reemplazar cursores / combinaciones complicadas al implementar cálculos recursivos, y también gané mucho en rendimiento.
Aquí hay detalles y código de ejemplo que hizo mejoras fantásticas en el rendimiento: http://geekswithblogs.net/Rhames/archive/2008/10/28/calculating-running-totals-in-sql-server-2005---the-optimal. aspx
fuente
Suponiendo que MySQL aquí, use EXPLAIN para averiguar qué está pasando con la consulta, asegúrese de que los índices se usen de la manera más eficiente posible e intente eliminar los tipos de archivos. MySQL de alto rendimiento: optimización, copias de seguridad, replicación y más es un gran libro sobre este tema, al igual que el Blog de rendimiento de MySQL .
fuente
@Terrapin hay algunas otras diferencias entre isnull y coalesce que vale la pena mencionar (además del cumplimiento de ANSI, que es muy importante para mí).
Coalesce vs. IsNull
fuente
A veces, en SQL Server, si usa un OR en una cláusula where, realmente aumentará el rendimiento. En lugar de usar el OR, simplemente haga dos selecciones y únalas. Obtiene los mismos resultados a 1000x la velocidad.
fuente
Mire la cláusula where: verifique el uso de índices / verifique que no se esté haciendo nada tonto
fuente
En general, comenzaré con las uniones: eliminaré cada una de ellas de la consulta una por una y volveré a ejecutar la consulta para tener una idea de si hay una unión particular con la que tengo un problema.
fuente
En todas mis tablas temporales, me gusta agregar restricciones únicas (cuando corresponda) para crear índices y claves primarias (casi siempre).
fuente
Me he acostumbrado a usar siempre variables de enlace. Es posible que las variables de enlace no ayuden si el RDBMS no almacena en caché las declaraciones SQL. Pero si no utiliza variables de enlace, el RDBMS no tiene la posibilidad de reutilizar los planes de ejecución de consultas y las instrucciones SQL analizadas. Los ahorros pueden ser enormes: http://www.akadia.com/services/ora_bind_variables.html . Trabajo principalmente con Oracle, pero Microsoft SQL Server funciona casi de la misma manera.
En mi experiencia, si no sabe si está utilizando variables de enlace, probablemente no lo esté. Si el idioma de su aplicación no los admite, busque uno que sí lo haga. A veces puede arreglar la consulta A utilizando variables de enlace para la consulta B.
Después de eso, hablo con nuestro DBA para averiguar qué está causando más dolor al RDBMS. Tenga en cuenta que no debe preguntar "¿Por qué esta consulta es lenta?" Eso es como pedirle a su médico que saque su apéndice. Seguro que su consulta podría ser el problema, pero es muy probable que algo más esté saliendo mal. Como desarrolladores, tendemos a pensar en términos de líneas de código. Si una línea es lenta, arregle esa línea. Pero un RDBMS es un sistema realmente complicado y su consulta lenta podría ser el síntoma de un problema mucho mayor.
Demasiados consejos de ajuste de SQL son ídolos de culto de carga. La mayoría de las veces el problema no está relacionado o está mínimamente relacionado con la sintaxis que usa, por lo que normalmente es mejor usar la sintaxis más limpia que pueda. Luego puede comenzar a buscar formas de ajustar la base de datos (no la consulta). Solo modifique la sintaxis cuando eso falle.
Al igual que cualquier ajuste de rendimiento, siempre recopile estadísticas significativas. No use el tiempo de reloj de pared a menos que sea la experiencia del usuario lo que está sintonizando. En cambio, mire cosas como el tiempo de CPU, las filas recuperadas y los bloques leídos del disco. Con demasiada frecuencia, las personas optimizan para algo incorrecto.
fuente
Primer paso: ¡Mira el plan de ejecución de consultas!
TableScan -> mal
NestedLoop -> meh advertencia
TableScan detrás de un NestedLoop -> DOOM!
SET STATISTICS IO ON
SET STATISTICS TIME ON
fuente
Ejecutar la consulta usando WITH (NoLock) es una operación bastante estándar en mi lugar. Cualquiera que sea sorprendido ejecutando consultas en las tablas de decenas de gigabytes sin que sea sacado y disparado.
fuente
Convierta las consultas NOT IN a LEFT OUTER JOINS si es posible. Por ejemplo, si desea encontrar todas las filas en la Tabla1 que no se utilizan por una clave externa en la Tabla2, puede hacer esto:
Pero obtienes un rendimiento mucho mejor con esto:
fuente
@ DavidM
En SQL Server, el plan de ejecución le da lo mismo: le dice qué índices están siendo alcanzados, etc.
fuente
Indice la (s) tabla (s) por el clm (s) por el que filtra
fuente
No necesariamente un truco de rendimiento de SQL per se, pero definitivamente relacionado:
Una buena idea sería usar memcached cuando sea posible, ya que sería mucho más rápido simplemente obtener los datos precompilados directamente de la memoria en lugar de obtenerlos de la base de datos. También hay un sabor de MySQL que se incorporó a memcached (de terceros).
fuente
Asegúrese de que la longitud de su índice sea lo más pequeña posible. Esto permite que el DB lea más claves a la vez del sistema de archivos, acelerando así sus uniones. Supongo que esto funciona con todos los DB, pero sé que es una recomendación específica para MySQL.
fuente
Cuido de:
fuente
Por lo general, la primera línea dentro de mis procedimientos almacenados, a menos que realmente necesite usar
@@ROWCOUNT
.fuente
En SQL Server, use la directiva nolock. Permite que el comando de selección se complete sin tener que esperar, generalmente otras transacciones para finalizar.
fuente
Retire los cursores donde no sean necesarios.
fuente
Elimine las llamadas a funciones en Sprocs donde muchas filas llamarán a la función.
Mi colega utilizó llamadas de función (obteniendo lastlogindate de userid como ejemplo) para devolver conjuntos de registros muy amplios.
Encargado de la optimización, reemplacé las llamadas de función en el sproc con el código de la función: obtuve el tiempo de ejecución de muchos sprocs de> 20 segundos a <1.
fuente
fuente
Me gusta usar
Encima
Cuando no necesito el soporte de argumentos múltiples que te da la fusión.
http://blog.falafel.com/2006/04/05/SQLServerArcanaISNULLVsCOALESCE.aspx
fuente
No prefije los nombres de Procedimiento almacenado con "sp_" porque todos los procedimientos del sistema comienzan con "sp_", y SQL Server tendrá que buscar más para encontrar su procedimiento cuando se lo llame.
fuente
Lecturas sucias -
Evita bloqueos muertos donde la integridad transaccional no es absolutamente necesaria (lo cual suele ser cierto)
fuente
Siempre voy al Analizador de SQL (si es un procedimiento almacenado con muchos niveles de anidamiento) o al planificador de ejecución de consultas (si se trata de unas pocas instrucciones SQL sin anidamiento) primero. El 90% del tiempo puede encontrar el problema de inmediato con una de estas dos herramientas.
fuente