2010-02-08 11 views
10

estoy manteniendo procedimientos almacenados para SQL Server 2005 y me gustaría poder utilizar una nueva característica en 2008 que permite la sugerencia de consulta: "optimizar para DESCONOCIDO"¿Esta consulta es equivalente a OPTIMIZAR POR DESCONOCIDO en SQL Server 2008?

Parece como si la siguiente consulta (escrito para SQL Server 2005) estima el mismo número de filas (es decir, la selectividad) como si se especifica la opción (OPTIMIZACIÓN dE DESCONOCIDO):

CREATE PROCEDURE SwartTest(@productid INT) 
AS 
DECLARE @newproductid INT 
SET @newproductid = @productid 

SELECT ProductID 
FROM Sales.SalesOrderDetail 
WHERE ProductID = @newproductid 

Esta consulta evita descubrimiento de parámetros declarando y el establecimiento de una nueva variable. ¿Es esto realmente una solución de SQL Server 2005 para la función OPTIMIZE-FOR-UNKNOWN? ¿O me estoy perdiendo algo? (Se agradecen los enlaces autoritativos, las respuestas o los resultados de las pruebas).

Más información: Una prueba rápida en SQL Server 2008 me dice que el número de filas estimadas en esta consulta es de hecho el mismo que si se especificara OPTIMIZE FOR UNKNOWN. ¿Es este el mismo comportamiento en SQL Server 2005? Creo que recuerdo haber oído una vez que, sin más información, SQL Server Optimizing Engine tiene que adivinar la selectividad del parámetro (por lo general, al 10% para los predicados de desigualdad). Todavía estoy buscando información definitiva sobre el comportamiento de SQL 2005. No obstante, no estoy seguro de que exista información ...

Más información 2: Para ser claros, esta pregunta solicita una comparación de la sugerencia de consulta DESCONOCIDA y la técnica de enmascaramiento de parámetros que describo.

Es una pregunta técnica, no una cuestión de resolución de problemas. Consideré muchas otras opciones y me decidí por esto. Entonces, el único objetivo de esta pregunta era ayudarme a ganar la confianza de que los dos métodos son equivalentes.

+0

Consulte Kimberly Tripp's articl http://www.sqlskills.com/blogs/kimberly/post/ProcsPSPandDNR.aspx y busque "EXACTAMENTE lo mismo que OPTIMIZAR POR DESCONOCIDO". Estoy dispuesto a confiar en ella :-) –

Respuesta

4

Bien, entonces he hecho algunos experimentos. Voy a escribir los resultados aquí, pero primero quiero decir que, según lo que he visto y sé, estoy seguro de que usando parámetros temporales en 2005 y 2008 es exactamente equivalente al uso de 2008 OPTIMIZE FOR UNKNOWN. Al menos en el contexto de procedimientos almacenados.

Así que esto es lo que he encontrado. En el procedimiento anterior, estoy usando la base de datos AdventureWorks. (Pero yo uso métodos similares y obtener resultados similares para cualquier otra base de datos) me encontré:

dbcc show_statistics ('Sales.SalesOrderDetail', IX_SalesOrderDetail_ProductID) 

Y veo las estadísticas con 200 pasos en su histograma. Al observar su histograma, veo que hay 66 filas de rango distintas (es decir, 66 valores distintos que no se incluyeron en las estadísticas como valores de igualdad). Agregue las 200 filas de igualdad (de cada paso), y obtengo un estimado de 266 valores distintos para ProductId en Sales.SalesOrderDetail.

Con 121317 filas en la tabla, puedo estimar que cada ProductId tiene 456 filas en promedio. Y cuando miro el plan de consulta para mi procedimiento de prueba (en formato XML) que veo algo así como:

... 
<QueryPlan DegreeOfParallelism="1" > 
    <RelOp NodeId="0" 
     PhysicalOp="Index Seek" 
     LogicalOp="Index Seek" 
     EstimateRows="456.079" 
     TableCardinality="121317" /> 
    ... 
    <ParameterList> 
    <ColumnReference 
     Column="@newproductid" 
     ParameterRuntimeValue="(999)" /> 
    </ParameterList> 
</QueryPlan> 
...  

así que sé donde el valor EstimateRows está viniendo (precisión de tres decimales) y observe que la ParameterCompiledValue atributo falta en el plan de consulta. Esto es exactamente lo que parece un plan cuando se utiliza 2008 OPTIMIZE PARA DESCONOCIDO

1

Interesante pregunta.

Hay un buen artículo sobre la programación SQL y Desarrollo API blog del equipo here que enumera las soluciones de solución, pre-SQL 2008 como:

  1. toque uso RECOMPILE lo que la consulta se vuelve a compilar cada vez que
  2. unparameterise la consulta
  3. dan valores específicos en OPTIMIZACIÓN dE pista
  4. uso de fuerza de un índice específico
  5. usar una guía de plan

Lo que me lleva al artículo this, que menciona su solución al uso de parámetros locales y cómo genera un plan de ejecución basado en estadísticas. Qué tan similar es este proceso al nuevo OPTIMIZADOR DE CONSEJO DESCONOCIDO, no lo sé. Mi corazonada es que es una solución razonable.

+0

Tengo la misma corazonada. Y su "No sé" es la pregunta que estoy haciendo ... Pero gracias por tomarse el tiempo para responder. –

4

He usado esa solución varias veces recientemente para evitar el rastreo de parámetros en SQL 2005 y me parece hacer lo mismo que OPTIMIZAR POR DESCONOCIDO en SQL 2008. Se solucionaron muchos problemas que tuvimos con algunos de nuestros procedimientos almacenados más grandes a veces simplemente colgando cuando se pasan ciertos parámetros.

+0

Eso es alentador. Parece ser lo mismo para mí también. Me pregunto si hay una manera de averiguarlo con certeza. –

0

He estado utilizando esta técnica de enmascaramiento de parámetros durante al menos el año pasado debido a problemas de rendimiento extraños, y ha funcionado bien, pero es MUY molesto para tiene que hacer todo el tiempo.

Tengo TAMBIÉN estado usando WITH RECOMPILE.

no me han controlado las pruebas porque no puedo desactivar selectivamente el uso de cada uno y se apaga automáticamente en el sistema, pero sospecho que el enmascaramiento de parámetros sólo ayudará SI se utiliza el parámetro. Tengo algunos SP complejos donde el parámetro no se usa en todas las declaraciones, y espero que WITH RECOMPILE fuera aún necesario porque algunas de las tablas de trabajo "temporales" no están pobladas (o incluso indexadas de forma idéntica, si intento sintonizar) el De la misma manera en cada ejecución, y algunas declaraciones posteriores no dependen del parámetro una vez que las tablas de trabajo ya están debidamente pobladas. He dividido algunos procesos en varios SP precisamente para que el trabajo realizado para completar una tabla de trabajo en un SP se pueda analizar y ejecutar correctamente contra WITH RECOMPILE en el próximo SP.

+0

AdaTheDev sugirió usar la sugerencia RECOMPILE. Decidí no hacerlo debido a mi situación particular (alto volumen, gran producción, etc.). Pero gracias por la técnica, es bueno saberlo. Lo pondré en mi caja de herramientas mental. –