L'Eliminazione delle Tabelle negli altri database

Stai visualizzando una vecchia versione di questo article. Visualizza la versione più recente.

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 this example we have added another join condition, which ensures that we only pick the matching row from tableB having the latest fromDate. In this case tableB will contain duplicates of the column B.id, so in order to ensure uniqueness the primary key has to contain the fromDate column as well. In other words the primary key of tableB is (B.id, B.fromDate).

Furthermore, since the subselect ensures that we only pick the latest B.fromDate for a given B.id we know that at most one row will match the join condition. We will again have the situation where joining with tableB cannot affect the number of rows in the result set. Since we do not select any columns from tableB, the whole join operation can be eliminated from the execution plan.

SQL Server 2005/2008 will deploy table elimination in this situation as well. We have not found a way to make Oracle 11g use it for this type of query. Queries like these arise in two situations. Either when you have a denormalized model consisting of a fact table with several related dimension tables, or when you have a highly normalized model where each attribute is stored in its own table. The example with the subselect is common whenever you store historized/versioned data.

See also

Commenti

Sto caricando i commenti......
Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.