Tenemos un generador de SQL que emite sentencias condicionales de SQL de forma genérica para campos específicos (que en aras de la discusión: etiquetaremos como myField
).
Si myField
es de tipo NVARCHAR
, podemos hacer una comparación de dicho campo contra una cadena de este modo: myField = 'foo'
.
Sin embargo, esto no funciona para campos de tipo NTEXT
. Por lo tanto, tenemos que hacer la comparación con un reparto: CAST(myField as NVARCHAR(MAX)) = 'foo'
. De hecho, esto funcionará si myField
es de tipo NVARCHAR
o NTEXT
.
¿Cuál es el éxito en el rendimiento de hacer el elenco antes mencionado en un campo que ya es de tipo NVARCHAR
? Espero que SQL Server sea lo suficientemente inteligente como para reconocer dinámicamente que myField
ya es de tipo NVARCHAR
(convirtiendo efectivamente CAST
en un no-op).
fuente
Respuestas:
Si el reparto de la columna tiene exactamente el mismo tipo de datos y longitud y el predicado de búsqueda es literal, de hecho parece ignorarlo o tratarlo como un no-op y hace un índice de búsqueda de igualdad.
Si el reparto de la columna es del mismo tipo de datos pero de mayor longitud y el predicado de búsqueda es un literal de cadena, provoca una exploración de índice. Obviamente, esto debe evitarse.
Si el reparto de la columna tiene el mismo tipo de datos y la misma longitud o mayor y el predicado de búsqueda es una variable local, agrega un operador escalar de cálculo al plan de ejecución. Esto llama
GetRangeThroughConvert
y genera un rango.Este rango se usa para hacer una búsqueda de índice y parece bastante eficiente
Código de prueba
fuente
En general,
CAST
matará el rendimiento porque invalida cualquier uso de búsquedas de índice como muestra el último ejemplo de Martin Smith. Lanvarchar(max)
transmisión a una longitud diferente significa un tipo de datos diferente: el hecho de que todonvarchar
sea irrelevante.Además de eso, el tipo de datos del lado derecho de la comparación también importa. Si se trata de una variable local o parámetro de una longitud diferente, un lado estará implícitamente
CAST
en el más amplio de los 2 tipos de datos (ver precedencia de tipos de datos ).Básicamente, si usted tiene un general
CAST
quenvarchar(max)
se bollix cosas. Consideraría arreglar el uso dentext
antes de agregarCAST
todo.La conversión puede no mostrarse en el plan de consulta. Ver el artículo del blog de Paul White
fuente
Solo una nota, Casting como este donde Datecreated es datetime
No interrumpe la capacidad de SQL para usar índices si los índices existen, y si no existen, puede resultar en el registro de un índice faltante.
De manera similar, cuando se convierte desde
int
haciatinyint
obigint
haciaint
, etc., la función de conversión no impide que SQL use índices SI el optimizador sabe que la operación de conversión no cambia el orden de clasificación de los 2 tipos de datos comparables.Aquí hay un montón de pruebas que puede ejecutar y ver el plan real usando Adventureworks2008R2
fuente