2009-11-12 20 views
5

tengo una consulta de la siguiente manera:llamada de función en la cláusula WHERE

SELECT * FROM Members (NOLOCK) 
WHERE Phone= dbo.FormatPhone(@Phone) 

Ahora aquí entiendo que el formato tiene que ser aplicado sobre la variable en la columna. Pero debo aplicarlo en variable para asignarlo a alguna otra variable local y luego usarlo (como se muestra a continuación).

Set @SomeVar = dbo.FormatPhone(@Phone) 

SELECT * 
    FROM Members (NOLOCK) WHERE Phone= @SomeVar 

¿Qué camino es mejor o ambos son buenos?

EDIT: ¿Y cómo es diferente de la primera consulta

SELECT * FROM Members (NOLOCK) 
WHERE dbo.FormatPhone(Phone) = @Phone 

Respuesta

7

Como es habitual con SQL, la consulta es en gran medida irrelevante sin saber que el esquema real se utiliza en contra.

¿Tiene un índice en Members.Phone? Si no, entonces no importa cómo se escriba la consulta, todos analizarán toda la tabla y obtendrán el mismo resultado (es decir, funcionarán mal). Si tienen un índice entonces la forma de escribir la consulta que hace la diferencia:

SELECT * FROM Members WHERE Phone= @Phone; 
SELECT * FROM Members WHERE Phone= dbo.FormatPhone(@Phone); 
SELECT * FROM Members WHERE dbo.FormatPhone(Phone)[email protected]; 

primera consulta se garantiza óptima, buscará el teléfono en el índice.
La segunda consulta depende de las características del dbo.FormatPhone. Puede o no usar una búsqueda óptima.
Se garantiza que la última consulta es incorrecta. Escaneará la mesa.

Además, eliminé la sugerencia de NOLOCK, parece el tema del día ... Ver syntax for nolock in sql. NOLOCK es siempre la respuesta incorrecta. Use aislamiento de instantáneas.

+0

Revisé la publicación y se trata de no usar NOLOCK con las instrucciones Actualizar/Insertar. t ver por qué es un problema aquí? –

+0

¿Quiere decir uso con (nolock) en lugar de NOLOCK? –

+0

¿Tiene * intención * de leer datos no comprometidos? ¿O agregó NOLOCK como solución para problemas de concurencia? –

4

La segunda es, sin duda prefiere. El primero evaluará la función para cada fila en la tabla, mientras que el otro hará el cálculo una sola vez.

+0

Además, la primera opción probablemente no podrá usar un índice. – Kuberchaun

+0

La evaluación de la función para cada fila estará allí si aplicamos la función en la columna de la tabla o variable? O ambas formas son las mismas? –

+0

No, si realiza el cálculo por adelantado, esencialmente está entregando la consulta una constante. –

5

Es casi seguro que obtendrá una mejor previsibilidad si asigna primero una variable, mucha dependencia en el optimizador en torno al determinismo frente al no determinismo.

0
SELECT * FROM Members (NOLOCK) 
WHERE Phone= dbo.FormatPhone(@Phone) 

en la consulta anterior, function dbo.FormatPhone se ejecutará para cada fila de la tabla Members.

cuando la consulta

Set @SomeVar = dbo.FormatPhone(@Phone) 

SELECT * 
FROM Members (NOLOCK) WHERE Phone= @SomeVar 

La segunda va a ejecutar la función de una sola vez. Así que creo que la segunda opción será más rápida en caso de que tenga grandes datos en la tabla de miembros.

+0

Gracias vrunda. Aquí estoy recibiendo diferentes respuestas y opiniones, aunque no lo hago cree que la función se ejecutará para cada fila en la primera consulta. ¿Tiene alguna referencia que lo pruebe? –