it-swarm-es.com

Formas de evitar las ansiosas operaciones de spool en SQL Server

Tengo un proceso ETL que implica un procedimiento almacenado que hace un uso intensivo de SELECT INTO declaraciones (mínimamente registradas y, por lo tanto, más rápidas ya que generan menos tráfico de registros). Del lote de trabajo que se lleva a cabo en un procedimiento almacenado en particular, varias de las operaciones más costosas son carretes ansiosos que parecen limitar los resultados de la consulta y luego copiarlos en la tabla que se acaba de realizar.

La documentación de MSDN sobre spoilers ansiosos es bastante escasa. ¿Alguien tiene una idea más profunda de si esto es realmente necesario (y bajo qué circunstancias)? Tengo algunas teorías que pueden o no tener sentido, pero no tengo éxito en eliminarlas de las consultas.

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

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

  • La consulta utiliza algunos UDF para la transformación de datos, como analizar 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 construirla?
  • Como una extensión de la pregunta anterior, ¿alguien tiene una visión más profunda de lo que impulsa o no esta operación en una consulta?
37

Tengo entendido que el spooling es que es un poco complicado 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 que pueda evitar un escaneo costoso. Si evitara el spooling, el costo del árbol de ejecución en el que se ubica aumentará y casi con toda seguridad el costo de toda la consulta aumentaría. No tengo una 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 confiar en su comportamiento.

Sin embargo, eso no significa que su plan de ejecución no pueda optimizarse, dependiendo exactamente de lo que esté haciendo y cuán volátiles sean sus datos de origen. Cuando estás haciendo un SELECT INTO, a menudo verá elementos de spool 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 reducir el nivel de aislamiento de la transacción a algo menos costoso y/o usar la sugerencia NOLOCK. En consultas complicadas y críticas para el rendimiento, he encontrado 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 para hacerlo.

En esta situación, si intentas READ UNCOMMITTED o la sugerencia NOLOCK, puede eliminar algunos de los spools. (Obviamente, no desea hacer esto si es probable que lo lleve a un estado inconsistente, pero los requisitos de aislamiento de datos de cada persona 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 ...

Tienes razón al decir que tus UDF también podrían ser los culpables. Si solo usa 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 una manera de escribirlos en línea con la consulta, probablemente sea por eso que podrían estar causando spooling).

Una última cosa que miraría es que, si está haciendo uniones que se pueden reordenar, intente usar una pista para forzar que el orden de unión ocurra en lo que sabe que es el orden más selectivo. Eso es un poco difícil de alcanzar, pero no está de más intentarlo si ya estás atascado en la optimización.

30
Grank