2009-12-10 11 views
12

Vorrei sapere se c'è un guadagno in realtà di prestazioni tra queste due opzioni:SQL Registrazione vs query separata in codice senza Join - Prestazioni

Opzione 1:

  • faccio una query SQL con un unisciti per selezionare tutti gli utenti e i loro ranghi.

Opzione 2:

  • faccio una query SQL per selezionare tutti gli utenti
  • prelevo tutti gli utenti e fare un altro query SQL per ottenere le fila di questo utente.

Nel codice, l'opzione due è più facile da realizzare per me. Questo è solo il modo in cui disegno il mio livello di Persistenza.

Quindi, vorrei sapere qual è l'impatto sulle prestazioni. Dopo quale limite dovrei prendere in considerazione l'opzione 1 anziché l'opzione 2?

risposta

12

In generale, il server DB è sempre più veloce all'entrata del codice dell'applicazione. Ricorda che dovrai eseguire una query aggiuntiva con un round trip di rete per ogni join. Tuttavia, se il tuo primo set di risultati è piccolo e gli indici sono ben sintonizzati, questo modello può funzionare correttamente.

Se stai facendo solo questo per riutilizzare la tua soluzione ORM, allora potresti combattere una battaglia persa. Ho sempre trovato che ho bisogno di set di dati di sola lettura che possono essere prodotti solo con SQL, quindi ora uso ORM per le operazioni CRUD per oggetto e SQL regolare per ricerche, report, aggregati, ecc.

+0

Cosa intendi per andata e ritorno? Per curiosità, che ORM stai usando? – Melursus

+0

Round trip significa passare dall'applicazione al server del database e viceversa. Quando si partecipa all'applicazione, si eseguono sottoquery in un ciclo, ovvero si eseguono N query aggiuntive/roundtrip, che presentano una scalabilità molto grave –

+0

Esattamente. Se la tua prima query avrà sempre un numero massimo di file sano (come, ad esempio, Super Model Chess Champions) e il tavolo secondario è veloce e piccolo (come i nomi dei figli), l'iscrizione all'app non ha un grande conseguenza. Se i join sono grandi o in continua crescita (tutti i tuoi clienti e i loro ordini) questo può diventare brutto in produzione dopo che sei passato ad altre cose. –

0

Dipende dal numero di utenti che anticipi. L'opzione uno sarà sicuramente più veloce, ma con una quantità ragionevole di dati, la differenza sarà trascurabile.

+0

Ogni viaggio di andata e ritorno fa male, anche quando ci sono solo 10 o 20 utenti, stai facendo molto più lavoro del necessario –

1

Se i ranghi sono valori statici, prendere in considerazione la memorizzazione nella cache dell'applicazione.

Se si ha bisogno di utenti frequentemente e ranghi solo raramente, si consideri il caricamento pigro dei ranghi. (ad esempio, query separate, ma la seconda query viene utilizzata solo occasionalmente).

Utilizzare il join se sono sempre necessari entrambi i set di dati e devono essere copie correnti del database.

Prototipare qualsiasi scelta probabile ed eseguire test delle prestazioni.

EDIT: Ulteriori riflessioni sul livello di persistenza, perché sto di fronte a questo uno io. Prendi in considerazione l'aggiunta di classi di tipo "persistente" che gestiscono i join come query di base e sono di sola lettura. Se questo si adatta al tuo particolare scenario, devi decidere, ma un sacco di accesso al database per molte app si basa sui join, che possono essere piuttosto grandi e complessi. Se riesci a gestirli in modo coerente con i tuoi oggetti persistenti e aggiornabili, può essere un grande vantaggio per l'architettura generale. Concettualmente, è come avere una vista nel database e interrogare la vista invece di scrivere un join, ma lo stai facendo tutto in codice.

+0

Hai qualche esempio o link sulle tue classi "Persitence-like"? – Melursus

+0

Nulla da poter postare online, dal momento che non sono ancora stati scritti! Ho scritto classi di entità, che si comportano molto come LINQ per entità SQL, ma sono popolate da codice "classico" ADO.NET. Ho anche classi di record attivi che incapsulano query a livello di tabella e codice di accesso ai dati e che generano istruzioni INSERT e UPDATE. Le classi di record attivo popolano entità da DataSet. Le classi di entità contengono metadati per supportare la funzione ActiveRecord. Useremo generatori di codice per costruirli in futuro. La stessa struttura dovrebbe funzionare per query complesse. Vorrei poter usare LINQ, ma non posso. –

0

In 99% situazioni si uniscono sarà più veloce.

Tuttavia, vi è una rara situazione in cui può essere più lento. Se stai facendo uno o più join sulla tabella con grandi dimensioni di riga e stai raggiungendo il limite della larghezza di banda della rete.

Ad esempio, c'è una colonna BLOB in T1 di 1 MB, si sta entrando in T2 che consiste di 100 righe per ogni riga T1. Il set di risultati sarebbe il conteggio di righe T1 multiplo 100.

Quindi, se si sta interrogando una riga T1 con join, si otterrà 100MB di risultati, se si recupera la riga T1 (1MB) e quindi si seleziona separata per recuperare 100 T2 per questo T1 il set di risultati sarà 1MB.