L'ottimizzazione delle query deve essere proattiva o reattiva?


23

Come sviluppatore di software e aspirante DBA, provo a incorporare le migliori pratiche quando progetto i miei database di SQL Server (il 99% delle volte il mio software si trova su SQL Server). Realizzo il miglior design possibile prima e durante lo sviluppo.

Ma, come qualsiasi altro sviluppatore di software, sono state aggiunte funzionalità, bug e solo un cambiamento dei requisiti che richiede oggetti di database modificati / creati.

La mia domanda è: l'ottimizzazione delle query dovrebbe essere proattiva o reattiva? In altre parole, poche settimane dopo alcune pesanti modifiche al codice / database, dovrei semplicemente riservare un giorno per verificare le prestazioni delle query e ottimizzare in base a ciò? Anche se sembra funzionare bene ?

O dovrei solo essere consapevole che le prestazioni inferiori alla media dovrebbero essere un controllo del database e tornare alla lavagna proverbiale?

L'ottimizzazione delle query può richiedere molto tempo e, a seconda della progettazione iniziale del database, potrebbe essere un vantaggio minimo. Sono curioso del modus operandi accettato.


7
L'ottimizzazione prematura è la radice di tutti i mali - DonaldKnuth
Drasill

@Drasill, puoi per favore ampliarlo? Il male come nel tempo di sviluppo sprecato?
Thomas Stringer

in realtà la tua domanda mi ha fatto pensare a questa famosa citazione ( vedi google ). Ma è più mirato allo sviluppo del software, penso che non si adatti davvero al DBA. Infine, mi direi "La micro ottimizzazione precoce è malvagia".
Drasill,

Vedi anche un vecchio post horror in codice su questo argomento :)
Drasill,

Risposte:


17

Entrambi, ma soprattutto proattivi

È importante testare durante lo sviluppo rispetto a volumi realistici e alla qualità dei dati. È incredibilmente comune avere una query in esecuzione su uno sviluppatore da 100 o 1000 righe per poi cadere a terra con 10 milioni di righe di produzione.

Ti permette anche di prendere appunti su "L'indice può aiutare qui". O "rivisitami". Oppure "risolverà con la nuova funzione xxx nella prossima versione di DB".

Tuttavia, alcune query non supereranno la prova del tempo. La distribuzione dei dati cambia o diventa esponenziale perché l'ottimizzatore decide di utilizzare un diverso tipo di join. In questo caso, puoi solo reagire.

Dire che, almeno per SQL Server, le varie query DMV "indice mancante" e "query più lunga" possono indicare aree problematiche prima della telefonata

Modifica: per chiarire ...

Proattivo non significa ottimizzare ogni query ora. Significa ottimizzare ciò che è necessario (eseguire frequentemente) su un tempo di risposta ragionevole. Per lo più ignora le query settimanali sui rapporti della domenica alle 3:00.


16

OK, morderò e prenderò una visione contrarian. Prima di tutto, direi che non dovresti mai iniziare facendo qualcosa che sai che ti porterà nei guai. Se desideri chiamarlo applicando le migliori pratiche, vai avanti. Questo è quanto dovrebbe essere proattivo.

Dopodiché, il tempo (e il denaro) si sprecano, quindi prosegui e consegna il tuo prodotto. Invece di dedicare un sacco di tempo alla progettazione, sintonizzando le query che potrebbero o non potrebbero mai rivelarsi dei colli di bottiglia, utilizzare quel tempo per ulteriori test, incluso il test di carico.

Quando scopri che qualcosa non funziona secondo le tue specifiche di progettazione, o se qualcosa sta cadendo nella parte inferiore del 10% o 20% dell'elenco dei tempi di risposta del tuo profiler, quindi investi il ​​tempo necessario per modificare qualunque cosa sia rotto.

In un mondo perfetto tutto sarebbe progettato perfettamente dall'inizio e sviluppato usando una sequenza logica di costruzione. Nel mondo reale ci sono vincoli sul budget e sul tempo e i dati dei test potrebbero non apparire come i dati di produzione. Per questo motivo, dico il buon senso per evitare i problemi in modo proattivo, ma concentri le tue risorse limitate sintonizzando le cose che si rivelano problemi reali invece di spendere tempo e denaro che probabilmente non hai nella ricerca di problemi immaginari o potenziali.


3
Non penso che sia affatto contrarian. Nessuno suggerisce che dovresti ottimizzare preventivamente tutto, ma dovresti testare tutto e ottimizzare le cose che sono evidenti che potrebbero / causeranno problemi nella produzione. È piuttosto diverso sia dall'ottimizzazione del codice senza dati sia dalla scoperta di ciò che è rotto / lento dopo la consegna del codice. Naturalmente c'è una linea: come hai detto, alla fine devi consegnare qualcosa. Ma penso che ci sia un buon equilibrio là dove puoi evitare di offrire qualcosa che fa schifo dal punto di vista delle prestazioni.
Aaron Bertrand

4
Aaron, concordò: non consegnare mai nulla che risulti dal punto di vista delle prestazioni e non caricare e costruire qualcosa senza pensare intensamente alle prestazioni e alla scalabilità. "Misura due volte, taglia una volta" appartiene agli adesivi per paraurti dei programmatori tanto quanto ai carpentieri. Allo stesso tempo, ho sentito che il tenore generale delle altre risposte era "proattivo> reattivo" e ho sentito che c'era un'opinione sottorappresentata che "realtà == reattivo" e quindi la chiave non è quella di perdere così tanto tempo essendo proattivo di non avere più tempo o denaro per affrontare le realtà aspre, spesso imprevedibili.
Joel Brown,

15

Farai 3 tipi di accordatura, 1 reattiva e 2 proattiva.

reattivo

All'improvviso, alcune query iniziano a causare problemi. Potrebbe essere a causa di un bug o di una funzionalità dell'applicazione, di una tabella che supera le aspettative, di un picco di traffico o di come "creativo" lo Strumento per ottimizzare le query. Potrebbe trattarsi di un affare di merda nel bel mezzo della notte, o potrebbe essere in risposta a una lentezza del sistema di natura non critica. In entrambi i casi, il carattere distintivo dell'accordatura reattiva è che hai già un problema . Inutile dire che vuoi fare il meno possibile. Il che ci porta a ...

Proattivi

Tipo 1: manutenzione ordinaria

In una sorta di programma, ogni pochi mesi o settimane a seconda della frequenza con cui lo schema cambia e della velocità con cui i dati crescono, è necessario rivedere l'output degli strumenti di analisi delle prestazioni del database (ad esempio report AWR per Oracle DBA). Sei alla ricerca di problemi incipiente, ovvero cose che sono in procinto di richiedere una messa a punto reattiva, così come la frutta bassa, elementi che non sono suscettibili di causare presto problemi ma che possono migliorare con un piccolo sforzo nella speranza di prevenire lontano -future. Quanto tempo dovresti dedicare a questo dipenderà da quanto tempo hai e da cos'altro potresti spenderlo, ma l'importo ottimale non è mai zero. Tuttavia, puoi facilmente ridurre l'importo che devi spendere facendo più di ...

Tipo 2: design corretto

L'ammonizione di Knuth contro "l'ottimizzazione prematura" è ampiamente nota e debitamente rispettata. Ma deve essere usata la definizione corretta di "prematuro". Alcuni sviluppatori di applicazioni, quando è autorizzato a scrivere le proprie query, hanno la tendenza ad adottare la prima query su cui si basano che è logicamente corretta e non prestano alcuna attenzione alle prestazioni, al presente o al futuro. Oppure possono testare un set di dati di sviluppo che semplicemente non è rappresentativo dell'ambiente di produzione (suggerimento: non farlo! Gli sviluppatori dovrebbero sempre avere accesso a dati realistici per i test). Il punto è che il momento giusto per ottimizzare una query è quando viene distribuita per la prima volta, non quando viene visualizzata in un elenco di SQL con prestazioni scarse e sicuramente non quando causa un problema critico.

Quindi cosa si qualificherebbe come ottimizzazione prematura in terra DBA? In cima alla mia lista sarebbe sacrificare la normalizzazione senza una necessità dimostrata. Sicuro che potresti mantenere una somma su una riga padre anziché calcolarla in fase di esecuzione dalle righe figlio, ma ne hai davvero bisogno? Se sei Twitter o Amazon, la de-normalizzazione strategica e il pre-calcolo possono essere i tuoi migliori amici. Se stai progettando un piccolo database di contabilità per 5 utenti, la struttura adeguata per facilitare l'integrità dei dati deve essere la massima priorità. Anche altre ottimizzazioni premature sono una questione di priorità. Non passare ore a modificare una query che viene eseguita una volta al giorno e impiega 10 secondi, anche se pensi di poterlo tagliare a 0,1 secondi. Forse hai un rapporto che viene eseguito per 6 ore al giorno, ma esplora la pianificazione come processo batch prima di investire tempo nella messa a punto. Non investire in un'istanza di reporting replicata in tempo reale separata se il carico di produzione non supera mai il 10% (supponendo che sia possibile gestire la sicurezza).

Testando dati realistici, ipotizzando con precisione modelli di crescita e di traffico (oltre alle quote per i picchi) e applicando la tua conoscenza delle stranezze dell'ottimizzatore della tua piattaforma, puoi distribuire query che funzionano (quasi) in modo ottimale non solo ora, ma in futuro e in condizioni tutt'altro che ideali. Quando si applicano le tecniche appropriate, è possibile prevedere e ottimizzare accuratamente le prestazioni della query (nel senso che ogni componente è veloce quanto deve essere).

(E mentre ci sei, impara le statistiche! )


Il design corretto rappresenta il 95% delle prestazioni e della scalabilità.
Mark Stewart,

6

In un mondo perfetto tutta la messa a punto verrebbe eseguita in fase di progettazione in modo proattivo e nulla sarebbe reattivo, ma il mondo non è perfetto. Scoprirai che i dati dei test a volte non sono rappresentativi, i casi di test sono stati persi, i carichi saranno inaspettatamente diversi e ci saranno bug che causano problemi di prestazioni. Queste situazioni possono richiedere una sintonia reattiva, ma ciò non significa che sia preferibile la sintonia reattiva. L'obiettivo dovrebbe essere sempre quello di metterli in primo piano.

La tua pianificazione per la messa a punto retroattiva è molto pragmatica. Quando si esegue il test, è necessario documentare i tempi e la produttività previsti e, a volte, è necessario integrare analisi che consentono di sapere quando i processi di produzione non soddisfano le specifiche di progettazione. In questo modo potresti essere in grado di identificare in anticipo quale codice deve essere ottimizzato. È quindi possibile determinare non solo quale sia il problema, ma perché non è stato individuato nella fase di progettazione / test.


5

Per me, i test delle prestazioni sono sempre stati parte del processo di sviluppo. Vuoi cambiare questa tabella, modificare questo rapporto, aggiungere questa funzione? Come parte del test, ti assicuri di poter confrontare le prestazioni individuali e complessive con le linee di base note e / o rispetto ai requisiti (ad esempio alcuni report vengono eseguiti in background o sono altrimenti automatizzati, quindi le prestazioni - o piuttosto la velocità - di ogni singola query nel sistema non è sempre la massima priorità).

IMHO, questo non dovrebbe essere affatto un processo reattivo: non dovresti mai aspettare fino a quando una modifica non provoca un problema di prestazioni in produzione per iniziare a reagire ad esso. Quando si effettua la modifica in sviluppo / test, ecc., È necessario verificare tali modifiche con dati simili su hardware simile con le stesse app e modelli di utilizzo simili. Non lasciare che questi cambiamenti si precipitino fuori dalla produzione e ti sorprendano. Questo accadrà quasi sempre quando non è conveniente trascorrere una giornata di tuning - budget per quel tempo di tuning con largo anticipo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.