Nella nostra applicazione, raccogliamo dati sulle prestazioni del motore automobilistico, fondamentalmente dati di origine sulle prestazioni del motore in base al tipo di motore, al veicolo che lo percorre e al design del motore. Attualmente, la base per i nuovi inserti di riga è un periodo di on-off del motore; monitoriamo le variabili di prestazione in base a una modifica dello stato del motore da attivo a inattivo e viceversa. Il relativo engineState
tabella seguente aspetto:In MySQL, qual è il progetto di query più efficace per unire tabelle di grandi dimensioni con molte o molte relazioni tra i predicati di join?
+---------+-----------+---------------+---------------------+---------------------+-----------------+
| vehicle | engine | engine_state | state_start_time | state_end_time | engine_variable |
+---------+-----------+---------------+---------------------+---------------------+-----------------+
| 080025 | E01 | active | 2008-01-24 16:19:15 | 2008-01-24 16:24:45 | 720 |
| 080028 | E02 | inactive | 2008-01-24 16:19:25 | 2008-01-24 16:22:17 | 304 |
+---------+-----------+---------------+---------------------+---------------------+-----------------+
Per un'analisi specifica, vorremmo analizzare il contenuto tabella basata su una granularità fila di minuti, piuttosto che l'attuale base di stato motore attivo/inattivo. Per questo, stiamo pensando di creare una semplice tabella productionMinute
con una riga per ogni minuto nel periodo che stiamo analizzando e unendo le tabelle productionMinute
e engineEvent
alle colonne di data e ora in ogni tabella. Quindi, se il nostro periodo di analisi è dal 2009-12-01 al 2010-02-28, creiamo una nuova tabella con 129.600 righe, una per ogni minuto di ogni giorno per quel periodo di tre mesi. Le prime righe della tabella productionMinute
:
+---------------------+
| production_minute |
+---------------------+
| 2009-12-01 00:00 |
| 2009-12-01 00:01 |
| 2009-12-01 00:02 |
| 2009-12-01 00:03 |
+---------------------+
Il join tra le tabelle sarebbero:
FROM engineState AS es
LEFT JOIN productionMinute AS pm ON pm.production_minute >= es.state_start_time
AND pm.production_minute <= es.event_end_time
Questa join, tuttavia, porta in primo piano molteplici tematiche ambientali:
- Il
engineState
tabella ha 5 milioni di righe e la tabellaproductionMinute
ha 130.000 righe - Quando unLa rigasi estende per più di un minuto (ad es. la differenza tra
es.state_start_time
ees.state_end_time
è maggiore di un minuto), come avviene nell'esempio precedente, non vi sono più righeproductionMinute
tabella che si uniscono ad una singola rigaengineState
tabella - Quando v'è più di un motore in funzione durante qualsiasi data minuto, anche secondo l'esempio precedente, più
engineState
righe della tabella si uniscono ad un singoloproductionMinute
fila
In testare nostra logica ed utilizzando solo un piccolo estratto tavolo (un giorno anziché 3 mesi, per la tabella productionMinute
) la query impiega più di un'ora per generare. Nella ricerca di questo articolo al fine di migliorare le prestazioni in modo che fosse possibile interrogare tre mesi di dati, i nostri pensieri erano di creare una tabella temporanea dallo engineEvent
, eliminando tutti i dati della tabella che non sono critici per l'analisi e unendo il tabella temporanea alla tabella productionMinute
. Stiamo anche pianificando di sperimentare diversi join, in particolare un join interno, per vedere se ciò migliorerebbe le prestazioni.
Qual è il miglior design di query per l'unione di tabelle con le molte: molte relazioni tra i predicati di join come descritto sopra? Qual è il miglior tipo di join (sinistra/destra, interno)?
Un esempio concreto di quale tipo di rapporto si sta tentando di generare sarebbe di aiuto. È possibile che non sia necessario espandere le osservazioni al minuto e creare direttamente i risultati. Inoltre, quali indici hai sulla tua tabella engineState? – Martin
I tuoi reclami numero 2 e 3 non sono problemi ambientali, sono problemi di progettazione. Quello che voglio dire è che non riesco a vedere niente di sbagliato in nessuno dei due: sono veri perché hai disposto i tuoi dati in quel modo. Devi descrivere il motivo per cui lo vedi come un problema e chiarisci cosa ti aspetti dal join che hai scritto (quale significato semantico vorresti assegnargli: D). – Unreason