Filtraggio e richieste di dati: recuperare tutte le voci o dividere i dati?

0

Sono in una situazione in cui non riesco a decidere quale approccio sia il più ottimale (rendimento saggio) pur essendo mantenibile allo stesso tempo (nel senso di avere una logica chiara).

La domanda è posta nel contesto di un'applicazione web Django, ma immagino che si applichi a qualsiasi scenario correlato.

Nel mio scenario stiamo visitando un particolare percorso che mostra molte partite in un campionato o torneo associato a una particolare stagione:

URL: season/<season_id>/

Quota ORM associata Django: season.match_set.all()

Una stagione ha molte divisioni e, ovviamente, le partite sono composte da squadre. Il cliente può filtrare per divisione e / o per squadra. Questi filtri possono anche essere inclusi nell'URL (in modo che gli utenti possano condividerli, già filtrati), ovvero season/<season_id>/#division=<division_name> , quindi le corrispondenze appartenenti alla divisione specificata vengono filtrate.

Tuttavia, anche quando visiti una rotta che include un filtro, viene eseguita l'intera query: season.match_set.all() .

Ed ecco ciò di cui non posso decidere. In termini di efficienza, sarebbe meglio semplicemente recuperare le corrispondenze relative a tale divisione:

season.match_set.filter(division=division)

Tuttavia, potrebbe essere piuttosto comune che gli utenti usino i filtri nella pagina, cambino tra loro, ecc. Che, se usiamo il secondo approccio, significherebbe ovviamente richieste aggiuntive che significherebbero anche colpi di database aggiuntivi per recuperare il filtro le partite. Questo non accadrebbe con il primo approccio dato che abbiamo tutti i dati impostati dall'inizio: solo una richiesta e un hit del database (anche se più pesante).

Potremmo provare a ottimizzare il secondo approccio memorizzando i dati filtrati come richiesto; cioè se abbiamo una stagione con tre divisioni e l'utente filtra in base a Division 1 ( richiesta 1 ), lo memorizziamo da qualche parte (nella parte client, immagino), quindi se lui / lei filtra per Division 2 ( richiesta 2 ) facciamo lo stesso e lo aggiungiamo ai dati esistenti, e infine se l'utente filtra di Division 1 di nuovo lo otteniamo semplicemente dai dati memorizzati e possiamo risparmiarci da eseguendo richiesta 3 .

Tuttavia, temo di avere una logica e un codice chiari come ho detto prima, perché questo ultimo approccio di ottimizzazione può facilmente diventare davvero funky e inaffidabile.

La mia domanda: qual è l'approccio da fare? Questo è uno scenario abbastanza comune quindi immagino ci debba essere un consenso su quale sia l'approccio più efficiente: recuperare tutte le voci del database ed eseguire una sola richiesta o eseguire richieste multiple e query di database e ottenere dati mentre vengono richiesti?

    
posta dabadaba 25.01.2017 - 11:49
fonte

1 risposta

2

No, non c'è un consenus. Devi usare il tuo giudizio.

Il motivo per cui non esiste un consenso è che soluzioni diverse siano appropriate in diverse situazioni. Quello che stai affrontando è una questione di trade-off - requisiti ortogonali multipli che sono tutti importanti, ma non tutti possono essere soddisfatti simultaneamente. Ecco alcuni dei compromessi coinvolti:

  • utilizzo della memoria rispetto alla velocità: il caching dei risultati di una query per il riutilizzo da query successive aumenta il peed delle query successive (non il primo) al prezzo dell'utilizzo di più memoria. Come risolvere questo trade-off dipende da quanto apprezzi le risposte veloci rispetto al costo di acquistare più RAM.

  • velocità della prima query rispetto alla velocità delle query in generale: il recupero di tutti i risultati anche per una query filtrata richiede più tempo del recupero di un sottoinsieme, ma offre la possibilità di accelerare le query successive. Come risolvere questo trade-off dipende da quante prime query o query successive ti aspetti, o da quanto importanti risposte fast vs costantemente siano rivolte ai tuoi utenti ( chiedi a un esperto di UX: paradossalmente, le persone potrebbero preferire una risposta consistentemente non molto veloce a una a volte veloce, a volte lenta).

  • comodità d'uso e complessità di programmazione: il calcolo del risultato di una query dai risultati memorizzati di una query precedente può accelerare la risposta eliminando costosi I / O, ma richiede una programmazione complicata con maggiore potenziale per scadenze e difetti mancati. La complessità vale il suo prezzo? Questa è una domanda a cui solo la direzione del progetto può rispondere. Se il progetto ha un strong requisito "deve rispondere con 100ms 99% delle volte" allora la logica aggiuntiva potrebbe essere indispensabile. Se il requisito più difficile è "Deve essere dal vivo domani" potrebbe non esserlo.

Puoi vedere che queste sono tutte domande alle quali puoi rispondere meglio di quanto possiamo. Possiamo solo suggerire domande da porsi.

    
risposta data 25.01.2017 - 15:54
fonte