Fare motori di database diversi da SQL Server comportarsi in questo modo?
-
05-10-2019 - |
Domanda
Ho una stored procedure che va qualcosa come questo (pseudo codice)
storedprocedure param1, param2, param3, param4
begin
if (param4 = 'Y')
begin
select * from SOME_VIEW order by somecolumn
end
else if (param1 is null)
begin
select * from SOME_VIEW
where (param2 is null or param2 = SOME_VIEW.Somecolumn2)
and (param3 is null or param3 = SOME_VIEW.SomeColumn3)
order by somecolumn
end
else
select somethingcompletelydifferent
end
Tutto ha funzionato bene per un lungo periodo di tempo. Improvvisamente, la query si mise a correre per sempre se param4 era 'Y'. Modifica del codice a questo:
storedprocedure param1, param2, param3, param4
begin
if (param4 = 'Y')
begin
set param2 = null
set param3 = null
end
if (param1 is null)
begin
select * from SOME_VIEW
where (param2 is null or param2 = SOME_VIEW.Somecolumn2)
and (param3 is null or param3 = SOME_VIEW.SomeColumn3)
order by somecolumn
end
else
select somethingcompletelydifferent
E funziona di nuovo entro i parametri previsti (15 secondi o giù di lì per 40.000 record). Questo è con SQL Server 2005. Il nocciolo della mia domanda è questa particolare specifica "funzione" per SQL Server, o si tratta di una caratteristica comune tra RDBMS' in generale che:
- Le query che ha funzionato bene per due anni solo smettere di lavorare come dati cresce.
- Il "nuovo" piano di esecuzione distrugge la capacità del server di database per eseguire la query, anche se un logicamente equivalenti percorsi alternativi bene?
Questo può sembrare una tirata contro SQL Server, e suppongo in una certa misura lo è, ma io davvero non voglio sapere se gli altri a sperimentare questo tipo di realtà con Oracle, DB2 o qualsiasi altro RDBMS. Anche se ho una certa esperienza con gli altri, ho solo visto questo tipo di volume e la complessità su SQL Server, quindi sono curioso di sapere se altri con grandi database complessi hanno un'esperienza simile in altri prodotti.
Soluzione
Ci potrebbe essere un paio di cause
1) sono le statistiche aggiornate?
2) si potrebbe essere affetti da sniffing dei parametri
A proposito di questo tipo di cose
dove (param2 è nullo o param2 = SOME_VIEW.Somecolumn2)
Date un'occhiata a usi Colonna = @ Param OR @ param IS NULL nella clausola WHERE? Non, non esegue
Altri suggerimenti
mi immagino questa istanza specifica del problema, e tutte le condizioni che portano a questo avvenimento sono specifiche per SQL server - probabilmente anche l'edizione. (Ad esempio SQL Server 2008 si sarebbe comportato in modo diverso.)
Ma questa è una "caratteristica" generale di ottimizzatori di query. Guardano la query e cercare di fare un'ipotesi informata su ciò che verrà eseguito il più veloce. Come gli utenti, abbiamo poco controllo diretto se le sceglie Optimizer (diciamo) un indice di scansione o di un indice di ricerca, ma possono influenzare indirettamente fornendo modi alternativi di esprimere la stessa cosa, per vedere se che richiama migliorato tempo di esecuzione.
Se non ci sono state altre modifiche allo schema che potrebbero influenzare la query, quindi controllare che le statistiche dell'indice vengono aggiornate. Usiamo un processo batch settimanale per fare questo.