2010-01-04 13 views
9

Cuando ejecuto cierto procedimiento almacenado por primera vez, demora aproximadamente 2 minutos. Cuando lo ejecuto por segunda vez, termina en unos 15 segundos. Supongo que esto es porque todo se almacena en caché después de la primera ejecución. ¿Puedo "calentar el caché" antes de ejecutar este procedimiento por primera vez? ¿La información en caché solo se usa cuando llamo nuevamente al mismo procedimiento almacenado con los mismos parámetros o lo usaré si invoco el mismo procedimiento almacenado con parámetros diferentes?Pregunta de caché del servidor SQL

Respuesta

9

Cuando realiza su consulta, los datos se leen en la memoria en bloques. Estos bloques permanecen en la memoria pero se "envejecen". Esto significa que los bloques están etiquetados con el último acceso y cuando el servidor Sql requiere otro bloque para una nueva consulta y la memoria caché está llena, el bloque utilizado menos recientemente (el más antiguo) es expulsado de la memoria. (En la mayoría de los casos, los bloques de escaneo de tablas completas se actualizan de forma instantánea para evitar que los escaneos de tabla completos rebasen la memoria y bloqueen el servidor).

Lo que está sucediendo aquí es que los bloques de datos en la memoria de la primera consulta no han sido eliminados todavía, así que pueden usarse para su segunda consulta, lo que significa que se evita el acceso al disco y mejora el rendimiento.

Entonces, lo que su pregunta realmente es preguntar es "¿Puedo obtener los bloques de datos que necesito en la memoria sin leerlos en la memoria (en realidad haciendo una consulta)?". La respuesta es no, a menos que desee almacenar en caché todas las tablas y hacer que residan permanentemente en la memoria, lo cual, a partir del tiempo de consulta (y por lo tanto del tamaño de datos) que está describiendo, probablemente no sea una buena idea.

Su mejor apuesta para la mejora del rendimiento es ver sus planes de ejecución de consultas y ver si el cambio de sus índices podría dar un mejor resultado. Hay dos áreas principales que pueden mejorar el rendimiento aquí:

  • creando un índice en la consulta podría utilizar uno para evitar consultas ineficientes y escaneos completos de tabla
  • añadir más columnas a un índice para evitar una segunda lectura de disco. Por ejemplo, tiene una consulta que devuelve las columnas A y B con una cláusula where en A y C y tiene un índice en la columna A. Su consulta utilizará el índice para la columna A que requiere una lectura de disco pero luego requiere un segundo disco pulse para obtener las columnas B y C. Si el índice tenía todas las columnas A, B y C, se puede evitar el segundo disco para obtener los datos.
-1

El plan de ejecución (la información en caché para su procedimiento) se reutiliza cada vez, incluso con diferentes parámetros. Es uno de los beneficios de usar procs almacenados.

La primera vez que se ejecuta un procedimiento almacenado, SQL Server genera un plan de ejecución y lo coloca en el caché de procedimientos.

Ciertos cambios en la base de datos pueden desencadenar una actualización automática del plan de ejecución (y también puede exigir explícitamente una recompilación).

Los planes de ejecución se eliminan de la memoria caché de procedimientos según su "antigüedad". (de MSDN: los objetos a los que se hace referencia con poca frecuencia pronto serán desasignados, pero no se desasignan a menos que se requiera memoria para otros objetos).

No creo que haya ninguna forma de "calentar el caché", excepto para realizar el proceso almacenado una vez. Esto garantizará que haya un plan de ejecución en el caché y que cualquier llamada posterior lo reutilizará.

información más detallada está disponible en la documentación de MSDN: http://msdn.microsoft.com/en-us/library/ms181055(SQL.90).aspx

+4

Su respuesta, aunque no puedo ver nada malo en ello, no ve el punto. La compilación de consultas no toma 1m45s, por lo que este no es el problema del OP. Los problemas de almacenamiento en caché de los OP tienen que ver con el caché de la página de datos, no con el caché del plan de ejecución. – erikkallen

3

No creo que la generación del plan de ejecución costará más que 1 segundo.

Creo que la diferencia entre la primera y la segunda ejecución se debe al almacenamiento en caché de los datos en la memoria.

Los datos en la memoria caché pueden reutilizarse mediante cualquier consulta adicional (procedimiento almacenado o selección simple).

Puede 'calentar' la caché leyendo los datos a través de cualquier selección que lea los mismos datos. Pero eso incluso costará unos 90 segundos también.

2

Puede consultar el plan de ejecución para averiguar qué tablas e índices utiliza su consulta. A continuación, puede ejecutar algunos SQL para obtener los datos en la memoria caché, según lo que vea.

  • Si ves un índice agrupado buscan, sólo tiene que hacer SELECT * FROM my_big_table para obligar a todas las páginas de datos de la tabla en la memoria caché.
  • Si ve una búsqueda de índice no agrupado, puede intentar SELECT first_column_in_index FROM my_big_table.

Para forzar una carga de un índice específico, también puede utilizar la sugerencia de tabla WITH(INDEX(index)) en las consultas de preparación de memoria caché.

Cuestiones relacionadas