Domanda

Ho appena visto questa definizione di funzione:

create function dbo.f (@a int,  @b int)  
returns integer
as  
begin 
return  case when 
        not exists (Select * from t1 where t1.col1 = @a)
        AND @b > 0
        then 1 else 0 end
end
GO

Vedere un non esiste Ho pensato che l'attenzione tabella completa scansione e ha cercato di migliorarlo

create function dbo.f (@a int,  @b int)  
returns integer
as  
begin 
return  case when 
        exists (Select * from t1 where t1.col1 = @a)
        OR @b > 0
        then 0 else 1 end
end

GO

La mia sensazione è che questa trasformazione potrebbe essere stato fatto da un ottimizzatore. Sembra essere dritto in avanti, ma come posso essere sicuro se lo fa?

Commenta la risposta di Igor: (Confronto fissato grazie a Matts commento)

Questo mi spinge a quanto segue:

create function dbo.f (@a int,  @b int)  
returns integer
as  
begin 
 IF @b <= 0
   RETURN 0

 IF exists (Select * from t1 where t1.col1 = @a)
   RETURN 0

  RETURN 1
end
GO
È stato utile?

Soluzione

Una cosa che si potrebbe fare per confrontare queste due versioni è di rinominare uno di loro a f_old e entrambi eseguire all'interno dello stesso lotto, mentre tra cui il piano di esecuzione reale e statistiche IO. Da lì, si tratta di una semplice questione di confronto tra i piani e le statistiche IO di ciascuno.

Una cosa è necessario essere cauti è che nella vostra prima dichiarazione si doveva IF @b> 0. Nella sua seconda dichiarazione che hai se @b <0. Che cosa succede se @b = 0? Non hai coperto questa possibilità.

Infine, immagino vi accorgerete che i vostri pensieri riguardo NON ESISTE vs. esiste è corretta. EXISTS elaborerà finché la condizione è soddisfatta. NOT EXISTS richiede una scansione della tabella (se non indicizzato) e un indice di scansione (se indicizzata). Su un tavolino, non si vede un enorme guadagno di prestazioni, ma è sempre meglio per progettare la tua logica intorno ESISTE, al contrario di NON ESISTE.

Matt

Altri suggerimenti

Sono abbastanza sicuro del server SQL sarebbe calcolare il Select * from t1 ... prima, e solo allora verificare se esiste o no il risultato. Se questo è vero, allora entrambe le versioni dovrebbero essere speedwise essenzialmente identica. Mi chiedo se si potesse provare tale procedura eseguendo queste funzioni su due grandi tavoli, e vedere se v'è un diverso coerente nel tempo necessario per le funzioni di cambio?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a dba.stackexchange
scroll top