2009-11-12 12 views
5

Ho una domanda, come di seguito:funzione in cui la clausola

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

Ora qui capisco che la formattazione deve essere applicato sulla variabile sulla colonna. Ma dovrei applicarlo sulla variabile per assegnare ad un'altra variabile locale quindi usarlo (come sotto).

Set @SomeVar = dbo.FormatPhone(@Phone) 

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

Qual è il modo migliore o entrambi sono buoni?

EDIT: E come è prima query diverso da

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

risposta

7

Come al solito con SQL, la query è in gran parte irrilevante senza conoscere lo schema effettivo utilizzato contro.

Avete un indice su Members.Phone? Se no, allora non fa differenza il modo in cui scrivi la query, eseguiranno tutti la scansione dell'intero tavolo ed eseguiranno lo stesso (cioè eseguiranno male). Se si hanno un indice poi il modo in cui si scrive la query fa la differenza:

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

prima query è garantita ottimale, cercherà il telefono sull'indice.
La seconda query dipende dalle caratteristiche del dbo.FormatPhone. Può o non può usare una ricerca ottimale.
L'ultima query è garantita come non valida. Scansionerà il tavolo.

Inoltre, ho rimosso il suggerimento NOLOCK, sembra il tema del giorno ... Vedi syntax for nolock in sql. NOLOCK è sempre la risposta sbagliata. Usa l'isolamento dello snapshot.

+0

Ho letto il post e parla di non usare NOLOCK con le istruzioni Update/Insert. Ecco perché è un problema qui? –

+0

Intendi usare con (nolock) invece di NOLOCK? –

+0

Hai * intenzione * di leggere i dati non trasmessi? O hai aggiunto NOLOCK come soluzione alternativa per problemi di concorenza? –

4

Il secondo è decisamente preferibile. Il primo valuterà la funzione per ogni riga della tabella, mentre l'altra eseguirà il calcolo una sola volta.

+0

Inoltre, la prima opzione molto probabilmente non sarà in grado di utilizzare un indice. – Kuberchaun

+0

La valutazione della funzione per ogni riga sarà presente se applichiamo la funzione sulla colonna o sulla variabile della tabella? O entrambi i modi sono uguali? –

+0

No, se si esegue il calcolo in anticipo, si sta essenzialmente consegnando la query come costante. –

5

Quasi certamente si otterrà una migliore prevedibilità se si assegna prima a una variabile, molta dipendenza nell'ottimizzatore attorno al determinismo rispetto al non determinismo.

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

nella query precedente, function dbo.FormatPhone verrà eseguita per ogni riga della tabella Members.

quando seconda query

Set @SomeVar = dbo.FormatPhone(@Phone) 

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

che sarà eseguire la funzione una sola volta. Quindi penso che la seconda opzione sarà più veloce nel caso in cui tu abbia grandi dati nella tabella dei membri.

+0

Grazie vrunda. Sto ricevendo risposte e opinioni diverse qui, anche se non lo faccio crediamo che la funzione verrà eseguita per ogni riga nella prima query. Hai qualche riferimento che lo provi? –

Problemi correlati