Domanda

Scrivevo affermazioni SQL come

select * from teacher where (TeacherID = @TeacherID) OR (@TeacherID = -1)

leggi di più

e pass @Teacherid Value = -1 per selezionare tutti gli insegnanti

Ora sono preoccupato per la performance, puoi dirmi che è una buona pratica o una cattiva?

grazie molto

È stato utile?

Soluzione

Se TeacherID è indicizzato e stai passando un valore diverso da -1 come TeacherID Per cercare i dettagli di un insegnante specifico, questa query finirà per fare una scansione a tavola piena piuttosto che l'opzione potenzialmente molto più efficiente di cercare nell'indice per recuperare i dettagli dell'insegnante specifico ...

... a meno che tu non sia su SQL 2008 SP1 Cu5 e successivamente e usa il OPTION (RECOMPILE) suggerimento. Vedere Condizioni di ricerca dinamica in T-SQL Per l'articolo definitivo sull'argomento.

Altri suggerimenti

Lo usiamo in modo molto limitato nelle procedure memorizzate.

Il problema è che il motore del database non è in grado di mantenere un buon piano di query per questo. Quando si tratta di molti dati, questo può avere un grave impatto negativo sulle prestazioni.

Tuttavia, per set di dati più piccoli (direi meno di 1000 record, ma è un'ipotesi) dovrebbe andare bene. Dovrai testare nel tuo ambiente particolare.

Se è in una procedura memorizzata, potresti voler includere qualcosa come un WITH RECOMPILE opzione in modo che il Il piano è rigenerato su ogni esecuzione. Ciò aggiunge (leggermente) al tempo per ogni corsa, ma in diverse corse possono effettivamente ridurre il tempo medio di esecuzione. Inoltre, ciò consente al database di ispezionare la query effettiva e "corto circuito" le parti che non sono necessarie per ogni chiamata.

Se stai creando direttamente il tuo SQL e lo trasmetti, ti suggerirei di fare la parte che costruisce il tuo SQL un po 'più intelligente in modo che includa solo la parte della clausola dove hai effettivamente bisogno.


Un altro percorso che potresti considerare è l'utilizzo di tutte le query dell'Unione rispetto ai parametri opzionali. Per esempio:

SELECT * FROM Teacher WHERE (TeacherId = @TeacherID)
UNION ALL
SELECT * FROM Teacher WHERE (@TeacherId = -1)

Questo in realtà realizza esattamente la stessa cosa; Tuttavia, il piano di query è memorizzata nella cache. Abbiamo usato questo metodo anche in alcuni posti e abbiamo visto miglioramenti delle prestazioni rispetto all'uso con ricompila. Non lo facciamo ovunque perché alcune delle nostre domande sono estremamente complicate e preferirei avere un colpo di performance piuttosto che complicare ulteriormente.

Alla fine, però, devi fare molti test.


C'è una seconda parte qui che dovresti riconsiderare. SELECT *. È sempre preferibile nominare effettivamente le colonne che desideri restituire E per assicurarti di essere solo Restituire quelli di cui avrai effettivamente bisogno. Spostare i dati attraverso i confini della rete è molto costoso e in genere è possibile ottenere una buona dose di aumento delle prestazioni semplicemente specificando esattamente ciò che desideri. Inoltre, se ciò di cui hai bisogno è molto limitato a volte puoi fare Coprire gli indici In modo che il motore del database non debba nemmeno toccare le tabelle sottostanti per ottenere i dati desiderati.

Se sei davvero preoccupato per le prestazioni, potresti interrompere la procedura per chiamare due diversi proc: uno per tutti i record e uno in base al parametro.

If @TeacherID = -1
   exec proc_Get_All_Teachers
else
   exec proc_Get_Teacher_By_TeacherID @TeacherID

Ognuno può essere ottimizzato individualmente.

È il tuo sistema, confronta le prestazioni. Prendi in considerazione l'ottimizzazione della scelta più popolare. Se la maggior parte degli utenti selezionerà un singolo record, perché rafforzare la propria preformance solo per accogliere i pochi che Selct tutti gli insegnanti (e dovrebbero avere una ragionevole aspettativa di prestazioni.).

So che una singola query selezionata è più facile da mantenere, ma ad un certo punto facilità di manutenzione alla fine lascia il posto alle prestazioni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top