L'Eliminazione delle Tabelle negli altri database
Oltre a MariaDB, anche Microsoft SQL Server 2005/2008 e Oracle 11g supportano la Table Elimination. Dei due, Microsoft SQL Server 2005/2008 sembra vantare dell'implementazione più avanzata. La Table Elimination in Oracle 11g è stata confermata, ma non è allo stesso livello.
Per compararli, osserviamo la query seguente:
select A.colA from tableA A left outer join tableB B on B.id = A.id;
Quando si utilizza A come tabelle di sinistra, ci si assicura che la query restituisca almeno tante righe quante ne contiene. Per le righe dove la condizione Join (B.id = A.id) non è vera, la colonna selezionata (A.colA) conterrà il valore originale. La riga B.* conterrà solo valori NULL.
Tuttavia, l'insieme dei risultati potrebbe contenere più righe di quante sono presenti in tableA se la tabella tableB contiene duplicati della colonna B.id. Se A contiene una riga [1, "val1"] e B le righe [1, "other1a"],[1, "other1b"], allora saranno due le righe restituite dalla condizioni Join. L'unico modo per valutare esattamente il risultato, quindi, è accedere a entrambe le tabelle durante l'esecuzione della query.
Ma supponiamo che tableB contenga righe che rendono possibile piazzare un vincolo di unicità sulla colonna B.id, per esempio; questo generalmente si verifica se si tratta di una chiave primaria. In questa situazione sappiamo che otterremo esattamente il numero di righe presenti in tableA, perchè la Join con tableB non può introdurre duplicati. Inoltre, se non selezioniamo alcuna riga da tableB, l'accesso ad essa non è necessario. Possiamo allora rimuovere l'intera operazione Join dal piano di esecuzione.
Sia SQL Server 2005/2008, sia Oracle 11g utilizzano la Table Elimination nel caso appena illustrato. Osserviamo una query più complessa, dove Oracle fallisce.
select A.colA from tableA A left outer join tableB B on B.id = A.id and B.fromDate = ( select max(sub.fromDate) from tableB sub where sub.id = A.id );
In questo esempio è stata aggiunta un'ulteriore conizione Join, grazie alla quale ottieniamo la riga corrispondente di tableB che ha il valore formDate più alto. In questo caso tableB conterr dei duplicati della colonna B.id, perciò per assicurare l'unicit della chiave primaria deve contenere anche la colonna fromDate. In altre parole, la chiave primaria di tableB è (B.id, B.fromDate).
Inoltre, poiché la subquery assicura che otteniamo solo la B.fromDate più recente per ogni B.id, sappiamo che solo una riga può superare la condizione Join. Avremo di nuovo una situazione dove la Join con tableB non può influenzare il numero di righe presenti nel resultset. Poichè non selezioniamo alcuna colonna da tableB, l'intera operazione Join può essere rimossa dal piano di esecuzione.
SQL Server 2005/2008 utilizza l'Eliminazione delle Tabelle anche in questa situazione. Non abbiamo trovato invece un modo per far sì che Oracle 11g la utilizzi in questo tipo di query. Istruzioni come queste vengono usate in due situazioni: quando si ha un modello denormalizzato che consiste di una tabella alla quale sono collegate tabelle dimensionali, o quando si ha un modello altamente normalizzato dove ogni attributo è contenuto in una tabella apposita. Questo esempio con le subquery è abbastanza comune con i dati storicizzati o soggetti a versioning.
Vedi anche
- Questa pagina si basa sul seguente post: http://s.petrunia.net/blog/?p=58