2008-09-17 15 views
31

Tengo un proceso ETL que involucra un procedimiento almacenado que hace uso intensivo de las declaraciones SELECT INTO (mínimamente registradas y, por lo tanto, más rápidas, ya que generan menos tráfico de registro). Del lote de trabajo que tiene lugar en un particular almacenado el procedimiento almacenado, varias de las operaciones más costosas son carretes ansiosos que parecen simplemente almacenar en búfer los resultados de la consulta y luego copiarlos en la tabla que se acaba de realizar.Formas de evitar operaciones de spool ansiosas en SQL Server

La documentación de MSDN en eager spools es bastante escasa. ¿Alguien tiene una idea más profunda de si estos son realmente necesarios (y bajo qué circunstancias)? Tengo algunas teorías que pueden tener sentido o no, pero no tienen éxito en eliminarlas de las consultas.

Los archivos .sqlplan son bastante grandes (160kb), así que supongo que probablemente no sea razonable publicarlos directamente en un foro.

tanto, aquí hay algunas teorías que pueden ser susceptibles de respuestas específicas:

  • La consulta utiliza algunas UDF de transformación de datos, tales como el análisis fechas formateadas. ¿Esta transformación de datos requiere el uso de carretes ansiosos para asignar tipos sensibles (por ejemplo, longitudes de varchar) a la tabla antes de que la construya?
  • Como una extensión de la pregunta anterior, ¿alguien tiene una visión más profunda de lo que conduce o no esta operación en una consulta?

Respuesta

24

Mi comprensión de la cola de servidores es que es un poco un arenque rojo en su plan de ejecución. Sí, representa una gran parte de su costo de consulta, pero en realidad es una optimización que SQL Server realiza automáticamente para evitar el costoso re-escaneo. Si tuviera que evitar el spooling, el costo del árbol de ejecución en el que se encuentra aumentará y, casi con certeza, aumentará el costo de toda la consulta. No tengo ninguna idea particular de lo que en particular podría hacer que el optimizador de consultas de la base de datos analice la ejecución de esa manera, especialmente sin ver el código SQL, pero probablemente sea mejor que confíe en su comportamiento.

Sin embargo, eso no significa que su plan de ejecución no se pueda optimizar, dependiendo de lo que esté haciendo y cuán volátiles sean sus datos de origen. Cuando hace un SELECT INTO, a menudo verá elementos de cola en su plan de ejecución y puede estar relacionado con el aislamiento de lectura. Si es apropiado para su situación particular, puede intentar bajar el nivel de aislamiento de la transacción a algo menos costoso y/o usar la sugerencia NOLOCK. He encontrado en consultas complejas de rendimiento crítico que NOLOCK, si es seguro y apropiado para sus datos, puede aumentar enormemente la velocidad de ejecución de la consulta, incluso cuando no parece haber ninguna razón por la que debería.

En esta situación, si se intenta READ UNCOMMITTED o la indirecta NOLOCK, puede ser capaz de eliminar algunos de los carretes. (Obviamente, no desea hacer esto si es probable que lo coloque en un estado incoherente, pero los requisitos de aislamiento de datos de todos son diferentes). El operador TOP y el operador OR ocasionalmente pueden causar spooling, pero dudo que esté haciendo alguno de esos en un proceso ETL ...

Tiene razón al decir que sus UDF también podrían ser los culpables. Si solo está utilizando cada UDF una vez, sería un experimento interesante intentar ponerlos en línea para ver si obtiene un gran beneficio de rendimiento. (Y si no puede encontrar la manera de escribirlos en línea con la consulta, probablemente sea por eso que podrían estar causando el spooling).

Una última cosa que vería es que, si está haciendo alguna unión que puede ser reordenada, intente usar una pista para forzar el orden de unión para que ocurra en lo que usted sabe que es el orden más selectivo. Es un poco de alcance, pero no está de más intentarlo si ya estás atascado optimizando.

+0

El aislamiento de lectura puede ser aplicable a las consultas de proceso desde un área de transición copiada de la fuente. Además, incluso si esto no soluciona mi problema particular, agrega un poco de conocimiento ya que esto no se menciona en ninguna de las publicaciones de MSDN que pude encontrar con respecto a las operaciones de spool ansiosas. – ConcernedOfTunbridgeWells

+0

Me alegra que haya sido de ayuda. Es posible que podamos ayudarle aún más si publicó el código SQL en cuestión (genérico si es necesario, por supuesto) – Grank

+0

Los spools ansiosos también son inferiores a los spools. No tengo ningún consejo sólido para hacer que sus eager se vuelvan lacios, pero el concepto de trabajar con solo una pequeña cantidad de datos a la vez y ponerlo a lo largo de la tubería sugiere un método alternativo: agrupe su trabajo en piezas más pequeñas de 1000 o 10000 filas a la vez. Se necesita bastante trabajo para llegar a un buen esquema de "caminar" que le permita pasar rápidamente a través de un índice agrupado a la vez, pero los resultados pueden ser sorprendentes ... – ErikE

Cuestiones relacionadas