2011-09-19 13 views
11

Código regla de análisis SR0007 para Studio 2010 proyectos de Visual base de datos establece que:¿El ajuste de columnas que aceptan nulos en ISNULL causa escaneos?

deberá indicar explícitamente cómo manejar los valores NULL en expresiones de comparación envolviendo cada columna que puede contener un valor NULL en una función ISNULL.

Sin embargo código de regla de análisis SR0006 se viola cuando:

Como parte de una comparación, una expresión contiene una referencia de columna ... Su código podría causar una mesa de análisis si se compara una expresión que contiene una referencia de columna

¿Esto también se aplica a ISNULL, o ISNULL nunca da como resultado una exploración de tabla?

Respuesta

17

Sí, provoca escaneos de tabla. (aunque parece optimizarse si la columna no es realmente anulable)

La regla SR0007 es un consejo muy pobre ya que hace que el predicado no se pueda enarbolar y significa que cualquier índice en la columna será inútil. Incluso si no hay un índice en la columna, podría hacer que las estimaciones de cardinalidad sean inexactas y afecten a otras partes del plan.

La categorización de la misma en la categoría Microsoft.Performance es bastante entretenida, ya que parece haber sido escrita por alguien que no entiende el rendimiento de la consulta.

Se afirma que la razón es

Si el código se comparan dos valores NULL o un valor NULL con cualquier otro valor , su código devolverá un resultado desconocido.

Mientras que la expresión en sí evaluar a unknown su código devuelve un resultado completamente determinista una vez que entienda que cualquier comparación =, <>, >, < etc con NULL evaluar como Unknown y que la cláusula WHERE sólo devuelve las filas donde las expresión evalúa a true.

Es posible que significan si ANSI_NULLS está apagado pero el ejemplo que dan en la documentación de WHERE ISNULL([c2],0) > 2; vs WHERE [c2] > 2; no se vería afectada por este ajuste de todos modos. Este establecimiento de

afecta a una comparación sólo si uno de los operandos de la comparación es ya sea una variable que es NULL o un valor NULL literal.

Los planes de ejecución que muestran las exploraciones vs solicitar o por debajo

CREATE TABLE #foo 
    (
    x INT NULL UNIQUE 
) 

INSERT INTO #foo 
SELECT ROW_NUMBER() OVER (ORDER BY @@SPID) 
FROM sys.all_columns 

SELECT * 
FROM #foo 
WHERE ISNULL(x, 10) = 10 

SELECT * 
FROM #foo 
WHERE x = 10 

SELECT * 
FROM #foo 
WHERE x = 10 
     OR x IS NULL 

enter image description here

+0

¿Qué hay que sintaxis en la cláusula 'ORDEN BY'? (He buscado en Google pero es algo difícil de buscar en Google ...) – AakashM

+0

@AakashM - Es la forma menos tipeada que he encontrado hasta ahora de ordenar por una constante con el fin de obtener una secuencia ascendente de números. 'over (ordenar por (SELECCIONAR 0))' o 'sobre (ordenar por @@ spid)' son alternativas. No puede usar un valor literal constante ya que SQL Server le da un error. La división por cero evita que se trate como una constante literal. No puede usar '1/0' como cosas de SQL Server que está tratando de ordenar por un ordinal de columna entera y arroja un error. –

+0

¡Oh, veo, '$' se interpreta como un literal 'dinero' con valor cero! Eso es sorprendente generosidad del analizador sintáctico, tengo que decir :) – AakashM

Cuestiones relacionadas