2010-01-11 6 views
8

Abbiamo un'applicazione Web in cui gli utenti eseguono query ad-hoc in base ai parametri immessi. Potrei anche menzionare che il tempo di risposta è di grande importanza per gli utenti.Vuoi inviare questo semplice SQL indietro per la rilavorazione?

La pagina Web crea dinamicamente un SQL da eseguire in base ai parametri immessi. Ad esempio, se l'utente immette "1" per "Business Unit" costruiamo uno SQL come questo:

SELECT * FROM FACT WHERE 
BUSINESS_UNIT = '1' 
--AND other criteria based on the input params 

ho scoperto che in cui l'utente non specifica un BUSINESS_UNIT la seguente query è costruito

SELECT * FROM FACT WHERE 
BUSINESS_UNIT LIKE '%' 
--AND other criteria based on the input params 

IMHO, questo è inutilmente (se non grossolanamente) inefficiente e garantisce l'invio del codice errato per la modifica ma dal momento che ho una velocità molto più alta di invio del codice per la rilavorazione rispetto ad altri, credo che potrei guadagnarmi una reputazione come " troppo schizzinoso. "

Se questa è una domanda inappropriata perché non è una codifica diretta Q, fammelo sapere e la eliminerò immediatamente. Sono molto confuso se le domande soggettive come questa siano permesse o no! Guarderò le tue risposte.

ty


Aggiornamento:

Sto usando un database Oracle.

La mia impressione è che Oracle non ottimizzi "LIKE '%'" rimuovendo la condizione e che lasciarla sia meno efficiente. Qualcuno potrebbe confermare?

+1

Sai chi altro era troppo schizzinoso? MICHELANGELO. – Ken

+2

Come si può vedere dalla risposta di Womp, in questa situazione non è necessario inviare il codice, poiché la maggior parte degli ottimizzatori di query SQL gestirà questo esempio in modo efficiente. Tuttavia, sono curioso di sapere se lo sviluppatore * sapeva o meno che sarebbe stato ottimizzato in tal modo. –

risposta

9

Anche se questo sembra gravemente inefficiente, l'ho appena testato su SQL Server, e Query Optimizer era abbastanza intelligente da filtrarlo.

In altre parole,

SELECT * FROM FACT WHERE 
BUSINESS_UNIT LIKE '%' 

e

SELECT * FROM FACT 

generati stesso piano esatto di query. Quindi non ci dovrebbe essere una differenza di prestazioni (a seconda del tuo motore DB credo), anche se sembra piuttosto sciatta.

Ciò potrebbe influire sulla decisione di reinvio o meno. Personalmente probabilmente lo farei, ma se sei già sotto una nuvola allora è qualcosa su cui probabilmente ti puoi rilassare, almeno in termini di prestazioni.

+0

Picchiami, ho appena finito di provarlo sulla mia macchina e sono giunto alla stessa conclusione. –

1

Vorrei rispedirlo e mi piace la domanda.

Tutta la revisione del codice è in qualche misura soggettiva. I criteri dovrebbero essere basati su una serie di fattori.

  • Funziona.

  • vuol soddisfare ragionevoli aspettative di prestazioni, manutenibilità, usabilità e scalabilità

Anche se non ho ancora testato questo particolare costrutto - Ho il sospetto (come si fa) questo codice farà cose orribili a il tuo server SQL. Quindi le prestazioni e la scalabilità sono chiamate in causa.

2

Quella domanda, con il BUSINESS_UNIT LIKE '%', non sembra abbastanza efficiente - suppongo che sarà forzare una scansione completa della tabella ...

Quindi, sì, cercherei di avere quella query rielaborato , per affrontare quel tipo di situazione in modo corretto - o, almeno, segnalerei questo problema tramite il nostro bug-tracker(Non sono sicuro della priorità che assegnerei, ma, comunque, il problema sarebbe registrato da qualche parte e qualcuno lo correggerà un giorno, quando non ci sono problemi con priorità più alta da trattare).

1

Lo scrittore voleva una dichiarazione fittizia in modo che lui/lei potesse aggiungere "e" a tutte le dichiarazioni successive. cambiarlo in una migliore "no-op" come 1 == 1 sarebbe d'aiuto. Oppure potrebbero fare un po 'più di lavoro e inserire il "dove" in modo intelligente.

2

SELECT * è una bandiera rossa. Specificare un elenco di colonne per la query.

14

Le due query sono completamente diversi (dal punto di vista di un set di risultati)

SELECT * FROM FACT; 

e

SELECT * FROM FACT WHERE 
BUSINESS_UNIT LIKE '%'; 

Il primo restituirà tutte le righe, la seconda, se ci sono NULL i valori di tali righe non verranno restituiti perché nulla rispetto a NULL è NULL e pertanto non soddisfa il predicato. Questo è come avrebbe funzionato in Oracle.

+0

Prima persona a notare il trucco "NULL". Credo che alcuni RDBMS gestiscano questo in modo diverso, questo è probabilmente il motivo per cui MS SQL Server può ottimizzarlo, mentre Oracle ovviamente non può (a meno che la colonna non sia NULL) – sleske

1

vorrei chiedere perché variabili di bind non vengono utilizzati (a meno che non ci sia una buona ragione in casi particolari):

SELECT * FROM FACT WHERE 
BUSINESS_UNIT = '1' 

Perché non è vero:

SELECT * FROM FACT WHERE 
BUSINESS_UNIT = :bu 
Problemi correlati