2016-04-02 27 views
5

Vengo dal mondo front-end nello sviluppo web, dove cerchiamo davvero di limitare il numero di richieste HTTP rilasciate (consolidando css, file js, immagini, ecc.).quanto è grave avere query di database "extra"?

Con connessioni db (MySQL), ovviamente non si desidera avere connessioni non necessarie, ma come regola generale, quanto è grave avere più piccole query? (eseguono rapidamente)

Chiedo perché sto spostando la mia applicazione in un ambiente cluster e dove prima stavo nascondendo alcune cose nella memoria del server (dato che stavo girando su un singolo server), ora sto provando a fare la mia app "senza stato" e nella mia attuale implementazione significa più piccole chiamate db. Questo mi aiuterà con il bilanciamento del carico (evitando sessioni appiccicose) e manterrò anche l'utilizzo della memoria del server.

Non stiamo parlando di un sacco di domande, forse chiamate 6-8 db anziché 2-4, restituendo ovunque da una manciata di record a poche migliaia di record. Ognuno di loro esegue rapidamente, meno di 30 ms (alcuni meno), ma non so se ci sia qualche "latenza di connessione" di cui dovrei preoccuparmi.

Grazie per la vostra comprensione.

+0

Brian Mi divertirò felicemente pontificando un po 'quando ho una possibilità ma non al momento – Drew

+0

Grazie, Drew, non vedo l'ora di approfondire. –

+0

Tutte le regole hanno eccezioni. Fai ciò che è meglio per la situazione a portata di mano. –

risposta

5

Risposta breve: (1) assicurarsi di stare nello stesso livello O grande, riutilizzare le connessioni, misurare le prestazioni; (2) pensa a quanto tieni alla coerenza dei dati.

Risposta lunga:

prestazioni

Rigorosamente dal punto di vista delle prestazioni, e in generale, se non si è già vicino al maxing fuori le vostre risorse di database, come ad esempio le connessioni max, questo non è probabile avere impatto maggiore. Ma ci sono alcune cose da tenere a mente:

  • le query "6-8" che sostituiscono le query "2-4" rimangono nello stesso tempo di esecuzione? per esempio. se l'attuale interazione del database è O(1), passerà a O(n)? O l'attuale O(n) passa a O(n^2)? Se sì, dovresti pensare a cosa significa per la tua applicazione
  • la maggior parte dei server di applicazioni può riutilizzare le connessioni di database esistenti o disporre di pool di connessioni di database persistenti; assicurati che la tua applicazione non stabilisca una nuova connessione per ogni query; altrimenti questo renderà ancora più inefficiente
  • in molti casi comuni, principalmente su tabelle più grandi con indici e join complessi, fare poche query con le chiavi primarie potrebbe essere più efficiente di unirsi a quelle tabelle in una singola query; questo sarebbe il caso se, mentre si fa come si unisce, il server non solo richiede più tempo per eseguire la query complessa, ma blocca anche altre query su tabelle interessate

generale sulle prestazioni, la regola generale è - sempre misurare.

Coerenza

prestazioni non è l'unico aspetto da considerare, però. Pensa anche a quanto tieni alla coerenza dei dati nella tua applicazione.

Ad esempio, considerare un caso semplice: tabelle A e B con relazione uno a uno e query per un singolo record utilizzando una chiave primaria.Se ti unisci a queste tabelle e recuperi i risultati utilizzando una singola query, riceverai un record da entrambi A e B o nessun record da entrambi, che è ciò che la tua applicazione si aspetta anche. Considerare ora se si divide in 2 query (e non si stanno utilizzando le transazioni con i livelli di isolamento preferiti) - si ottiene un record dalla tabella A, ma prima che si possa prendere il record corrispondente dalla tabella B, viene eliminato/aggiornato da un altro processo. Ora la tua applicazione ha un record da A ma nessuno da B.

La domanda generale qui è: ti interessa la conformità ACID dei tuoi dati relazionali per quanto riguarda le query che stai interrompendo? Se la risposta è sì, è necessario riflettere su come reagirà la logica dell'applicazione in questi casi specifici.

+0

Risposta meravigliosa, grazie per la tua opinione! Per quanto riguarda il tuo commento su "misura sempre", c'è uno strumento particolare che usi e che consiglio di misurare la tua performance in db? –

+0

Quando ColdFusion è in modalità di debug, può essere impostato per mostrare quanto tempo impiega una query per l'esecuzione. Può anche mostrare se la query è memorizzata nella cache –

+0

@BrianFitzGerald Suggerirei di misurare le prestazioni dell'applicazione durante il monitoraggio del database (cpu, ram, connessioni, query lente, ecc.). Se si dispone di un ambiente che è possibile utilizzare per il test del carico o se è possibile creare uno stack separato per questo scopo, dovrebbe essere abbastanza semplice iniziare con assedio, apachebench o uno strumento simile. –

4

6-8 query per una pagina Web? Di solito va bene. Lo faccio tutto il tempo.

Migliaia di righe restituite? Soffocare! Cosa farà il cliente con così tanti? SQL può fare più elaborazione, quindi restituire meno righe?

Con rare eccezioni, solo 1 connessione per pagina web.

Ogni query ha un sacco di spese generali. Ad esempio, INSERTing 100 righe in una tabella: 100 INSERT istruzioni a riga singola impiegheranno circa 10 volte il tempo di una singola riga di 100 righe INSERT. Quindi quando pratico utilizza meno viaggi di andata e ritorno verso il server. Questo diventa molto importante se la rete è una WAN. L'altro lato del globo è a 250 metri di distanza, solo per latenza. Un server nello stesso datacenter è probabilmente così vicino che la latenza può essere ignorata. In una WAN, utilizzare le stored procedure per ridurre al minimo i round trip.

Mi piace per tempo ogni query attivamente nel codice. Quindi, se percepisco un problema di prestazioni, cerco di vedere su quale query lavorare prima. Oppure usa SlowLog.

+1

Grazie Rick! Alcuni ottimi consigli lì. E una buona chiamata su migliaia di righe ... in pratica sta cercando di pre-compilare l'oggetto utente in modo da poter fare qualcosa come 'user.getFavorites()' (per esempio) e tutti i preferiti dell'utente saranno disponibili per l'uso. Ho capito che quelli possono essere caricati pigro, ecc., Ma prima di passare "senza stato" l'utente è stato memorizzato nella cache per sessione, quindi era un non-problema per precompilare una volta l'inizializzazione della sessione. In ogni caso, mi hai convinto a apportare alcune modifiche architettoniche alla mia app per evitare di caricare così tanti record per ogni richiesta :) –