Domanda

C'è qualche differenza di efficienza in un inner join esplicito o implicito?Per esempio:

SELECT * FROM
table a INNER JOIN table b
ON a.id = b.id;

contro

SELECT a.*, b.*
FROM table a, table b
WHERE a.id = b.id;
È stato utile?

Soluzione

Per quanto riguarda le prestazioni, sono esattamente le stesse (almeno in SQL Server).

PS:Essere consapevoli del fatto che IMPLICIT OUTER JOIN la sintassi è deprecata a partire da SQL Server 2005.(IL IMPLICIT INNER JOIN la sintassi utilizzata nella domanda è ancora supportata)

Deprecazione della sintassi JOIN "vecchio stile":Solo una cosa parziale

Altri suggerimenti

Personalmente preferisco la sintassi di join poiché rende più chiaro che le tabelle sono unite e come vengono unite.Prova a confrontare query SQL più grandi in cui selezioni da 8 tabelle diverse e hai molti filtri nel dove.Utilizzando la sintassi di join separi le parti in cui le tabelle sono unite dalla parte in cui stai filtrando le righe.

Su MySQL 5.1.51, entrambe le query hanno piani di esecuzione identici:

mysql> explain select * from table1 a inner join table2 b on a.pid = b.pid;
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref          | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
|  1 | SIMPLE      | b     | ALL  | PRIMARY       | NULL | NULL    | NULL         |  986 |       |
|  1 | SIMPLE      | a     | ref  | pid           | pid  | 4       | schema.b.pid |   70 |       |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
2 rows in set (0.02 sec)

mysql> explain select * from table1 a, table2 b where a.pid = b.pid;
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref          | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
|  1 | SIMPLE      | b     | ALL  | PRIMARY       | NULL | NULL    | NULL         |  986 |       |
|  1 | SIMPLE      | a     | ref  | pid           | pid  | 4       | schema.b.pid |   70 |       |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
2 rows in set (0.00 sec)

table1 ha 166208 righe; table2 ha circa 1000 righe.

Questo è un caso molto semplice;ciò non dimostra in alcun modo che il Query Optimizer non si confonderebbe e non genererebbe piani diversi in un caso più complicato.

La seconda sintassi presenta la possibilità indesiderata di un cross join:è possibile aggiungere tabelle alla parte FROM senza la clausola WHERE corrispondente.Questo è considerato dannoso.

La prima risposta che hai fornito utilizza la cosiddetta sintassi di join ANSI, l'altra è valida e funzionerà in qualsiasi database relazionale.

Sono d'accordo con grom sul fatto che dovresti usare la sintassi ANSI join.Come hanno detto, la ragione principale è la chiarezza.Invece di avere una clausola where con molti predicati, alcuni dei quali uniscono le tabelle e altri limitano le righe restituite con la sintassi di join ANSI, stai rendendo assolutamente chiaro quali condizioni vengono utilizzate per unire le tue tabelle e quali vengono utilizzate per limitare il risultati.

@lomaxx:Giusto per chiarire, sono abbastanza certo che entrambe le sintassi sopra indicate siano supportate da SQL Serv 2005.La sintassi seguente NON è tuttavia supportata

select a.*, b.*  
from table a, table b  
where a.id *= b.id;

Nello specifico, l'outer join (*=) non è supportato.

Per quanto riguarda le prestazioni, sono esattamente gli stessi (almeno in SQL Server), ma tieni presente che stanno deprecando questa sintassi di join e non è supportata immediatamente da SQL Server2005.

Penso che tu stia pensando agli operatori deprecati *= e =* vs."unione esterna".

Ho appena testato i due formati indicati e funzionano correttamente su un database SQL Server 2008.Nel mio caso hanno prodotto piani di esecuzione identici, ma non potevo dire con certezza che questo sarebbe sempre stato vero.

Su alcuni database (in particolare Oracle) l'ordine dei join può fare un'enorme differenza nelle prestazioni delle query (se sono presenti più di due tabelle).Su un'applicazione, in alcuni casi abbiamo riscontrato letteralmente due ordini di grandezza di differenza.L'uso della sintassi inner join ti dà il controllo su questo, se usi la giusta sintassi dei suggerimenti.

Non hai specificato quale database stai utilizzando, ma la probabilità suggerisce SQL Server o MySQL dove non fa alcuna differenza.

Come ha affermato Leigh Caldwell, il Query Optimizer può produrre diversi piani di query basati su quella che funzionalmente assomiglia alla stessa istruzione SQL.Per ulteriori letture su questo argomento, dai un'occhiata ai seguenti due post sul blog: -

Un messaggio dal team di Oracle Optimizer

Un altro post dal blog "Dati strutturati".

Spero che lo troverai interessante.

Per quanto riguarda le prestazioni, non dovrebbe fare alcuna differenza.La sintassi del join esplicito mi sembra più pulita poiché definisce chiaramente le relazioni tra le tabelle nella clausola from e non ingombra la clausola where.

Nella mia esperienza, l'utilizzo della sintassi cross-join-with-a-where produce spesso un piano di esecuzione con danni cerebrali, soprattutto se si utilizza un prodotto Microsoft SQL.Il modo in cui SQL Server tenta di stimare il conteggio delle righe della tabella, ad esempio, è terribilmente orribile.L'utilizzo della sintassi inner join offre un certo controllo su come viene eseguita la query.Quindi da un punto di vista pratico, data la natura atavica dell’attuale tecnologia dei database, è necessario adottare l’inner join.

Fondamentalmente la differenza tra i due è che uno è scritto alla vecchia maniera, mentre l'altro è scritto alla maniera moderna.Personalmente preferisco la scrittura moderna che utilizza le definizioni interno, sinistro, esterno e destro perché sono più esplicative e rendono il codice più leggibile.

Quando si ha a che fare con i join interni non c'è nemmeno una reale differenza nella leggibilità, tuttavia, potrebbe diventare complicato quando si ha a che fare con i join sinistro e destro poiché nel metodo precedente si otterrebbe qualcosa del genere:

SELECT * 
FROM table a, table b
WHERE a.id = b.id (+);

Quanto sopra è il vecchio modo in cui viene scritto un left join invece di quanto segue:

SELECT * 
FROM table a 
LEFT JOIN table b ON a.id = b.id;

Come puoi vedere visivamente, il modo moderno di scrivere lo script rende la query più leggibile.(A proposito, lo stesso vale per le giunzioni destre e un po' più complicato per le giunzioni esterne).

Tornando alla base, per il compilatore SQL non fa differenza il modo in cui viene scritta la query poiché le gestisce allo stesso modo.Ho visto un mix di entrambi nei database Oracle in cui molte persone vi hanno scritto, sia anziani che giovani.Ancora una volta, tutto dipende da quanto è leggibile la sceneggiatura e dal team con cui stai sviluppando.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top