Quali sono i diversi approcci al filtraggio sui dati aggregati?

4

Ho una caratteristica che sto costruendo che aggrega i dati su circa una dozzina di tavoli. Questi dati vengono aggregati da una query pesantemente unita. In questa pagina sono quindi disponibili molte opzioni di filtro, ordinamento, conteggio e visualizzazione che devono essere utilizzate in aggiunta a questo set di dati aggregati. C'è una condizione / filtro "globale" nella pagina in modo che carichi solo i dati dell'azienda che visualizza la pagina.

Il sito è costruito in Rails usando Postgres come database. Gran parte della funzionalità di filtro è già stata creata utilizzando gli ambiti su un modello ActiveRecord dei dati aggregati.

Sono arrivato ai seguenti modi possibili per risolvere questo problema:

  • Esegui l'intera query completa per ogni pagina caricata . Questo non sembra un buon approccio perché l'intera query dovrebbe essere eseguita più volte per cose come diversi conteggi nella pagina
  • Utilizza una vista del database (o una vista materializzata) . Funziona molto bene per il filtraggio, l'ordinamento, il conteggio delle esigenze, ma la costruzione della vista è molto lenta dal momento che deve guardare attraverso l'intero set di dati e non può essere portata solo all'account che guarda i dati. Se vado con una vista materializzata, devo aggiornare manualmente la vista in diversi punti logici nell'app.
  • Utilizza una tabella temporanea . Ciò sembrerebbe avere tutti i vantaggi di una vista ma caricare abbastanza velocemente poiché la query della tabella temporanea dovrebbe essere limitata alla sola società che visualizza la pagina. Il problema principale è che non ho trovato un buon modo per avere un ActiveRecord supportato da una tabella temporanea (soprattutto perché la query della tabella temporanea ha bisogno del contesto di cui la società sta visualizzando)
  • Utilizza una tabella fisica . Questo ha gli stessi vantaggi di una vista del database, tranne l'aggiornamento della tabella dovrebbe essere più veloce poiché il processo di aggiornamento può essere eseguito solo per il set di dati di una specifica azienda.

Ho difficoltà a valutare i pro ei contro di ciascun approccio. C'è qualcosa che mi manca? Qualche altro pro / contro o approccio a questo?

    
posta Andy Baird 18.11.2016 - 06:28
fonte

3 risposte

2

Alcune tecniche da considerare:

Caching

L'azienda ha bisogno che i dati aggregati siano al 100% fino al secondo preciso? In caso contrario, è possibile memorizzare i risultati degli aggregati in modo da salvare nuovamente alcuni calcoli.

I data warehouse prendono questo, spesso calcolando gli aggregati su una pianificazione fissa in modo che, sebbene non siano accurati al minuto, siano disponibili rapidamente.

De-Normalizzazione

Per i dati altamente transazionali, di solito è consigliabile normalizzare i dati il più possibile. Ma per gli aggregati, di solito è più performante per de-normalizzare i dati. I data warehouse utilizzano spesso schemi a fiocco di neve / stelle per ottenere prestazioni più elevate .

OLAP

I database OLAP combinano le due tecniche precedenti. Sono progettati per supportare la reportistica di gestione, l'analisi delle tendenze ecc.

Esempio

La mia azienda gestisce una serie di processi ETL durante la notte ogni notte per popolare il nostro data warehouse con una copia di tutti i dati necessari per la reportistica di gestione. Lo schema è strongmente de-normalizzato e gli aggregati e altri risultati intermedi vengono calcolati come parte del processo di caricamento. I rapporti eseguiti da questo database sono molto veloci. Non importa al business che i dati siano aggiornati fino a 24 ore.

    
risposta data 18.11.2016 - 10:47
fonte
0

Un'altra opzione che non è espressa nella domanda è di usare espressioni di tabella comuni SQL per anteporre la query a un'istruzione WITH per creare essenzialmente insiemi di dati interrogabili al volo. Esempio: link

Pro per questo approccio:

  • Evita l'uso di qualsiasi tipo di archiviazione (probabilmente rimane completamente in memoria?)

Contro per questo approccio:

  • Un CTE dovrebbe essere creato per ogni singola query sulla pagina. Ciò finirebbe per richiedere molto tempo nel mio caso, dove vengono eseguite diverse query di conteggio.
  • Nessun supporto immediato per questo con ActiveRecord, anche se postgres_ext sembra fornire un buon supporto per questa funzionalità
risposta data 21.11.2016 - 07:47
fonte
0
  • Esegui l'intera intera query per ogni pagina caricata.

Sebbene computivamente inefficiente, la reattività dell'app / pagina viene migliorata applicando i filtri / ordinamento in memoria (idealmente sul client) in risposta alle azioni degli utenti.

Puoi superare queste inefficienze ridimensionando il tuo back-end di conseguenza. Ma non puoi superare la velocità dei dati di andata e ritorno. quindi è probabile che un'app che utilizzi questo approccio sia "migliore" (se più costosa) di quella che esegue l'ordinamento nel database

    
risposta data 18.11.2016 - 10:08
fonte

Leggi altre domande sui tag