C’è qualcosa che non va con i join che non usano la parola chiave JOIN in SQL o MySQL?

Quando ho iniziato a scrivere query di database, non conoscevo ancora la parola chiave JOIN e, naturalmente, ho appena esteso ciò che già sapevo e ho scritto query come questa:

SELECT a.someRow, b.someRow FROM tableA AS a, tableB AS b WHERE a.ID=b.ID AND b.ID= $someVar 

Ora che so che questo è uguale a un INNER JOIN, trovo tutte queste query nel mio codice e mi chiedo se dovrei riscriverle. C’è qualcosa di puzzolente su di loro o stanno bene?


MODIFICARE:

Il mio sumrio della risposta : Non c’è niente di sbagliato in questa query, MA usando le parole chiave molto probabilmente renderà il codice più leggibile / manutenibile.

La mia conclusione : non cambierò le mie vecchie domande, ma correggerò il mio stile di scrittura e utilizzerò le parole chiave in futuro.

GRAZIE per le tue risposte!

Il filtraggio dei join utilizzando esclusivamente WHERE può essere estremamente inefficiente in alcuni scenari comuni. Per esempio:

 SELECT * FROM people p, companies c WHERE p.companyID = c.id AND p.firstName = 'Daniel' 

La maggior parte dei database eseguirà questa query letteralmente, prima prendendo il prodotto cartesiano delle tabelle delle people e delle companies e quindi filtrando quelli che hanno i campi id companyID e id corrispondenti. Mentre il prodotto completamente non vincolato non esiste da nessuna parte ma nella memoria e solo per un momento, il suo calcolo richiede del tempo.

Un approccio migliore consiste nel raggruppare i vincoli con i JOIN laddove rilevanti. Questo non è solo soggettivamente più facile da leggere ma anche molto più efficiente. Questa convenzione:

 SELECT * FROM people p JOIN companies c ON p.companyID = c.id WHERE p.firstName = 'Daniel' 

È un po ‘più lungo, ma il database è in grado di esaminare la clausola ON e usarla per calcolare direttamente il JOIN completamente vincolato, piuttosto che iniziare con tutto e quindi limitarsi. Questo è più veloce da calcolare (specialmente con grandi serie di dati e / o join di molti tavoli) e richiede meno memoria.

Cambio ogni query che vedo che utilizza la syntax “virgola JOIN “. Secondo me, l’unico scopo per la sua esistenza è la concisione. Considerando l’impatto sulle prestazioni, non penso che questo sia un motivo convincente.

Più verbale INNER JOIN, LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL OUTER JOIN derivano dalla syntax ANSI SQL / 92 per l’unione. Per me, questa verbosità rende il join più chiaro allo sviluppatore / DBA di quale sia l’intento con il join.

In SQL Server ci sono sempre piani di query da controllare, un output di testo può essere realizzato come segue:

 SET SHOWPLAN_ALL ON GO DECLARE @TABLE_A TABLE ( ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY, Data VARCHAR(10) NOT NULL ) INSERT INTO @TABLE_A SELECT 'ABC' UNION SELECT 'DEF' UNION SELECT 'GHI' UNION SELECT 'JKL' DECLARE @TABLE_B TABLE ( ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY, Data VARCHAR(10) NOT NULL ) INSERT INTO @TABLE_B SELECT 'ABC' UNION SELECT 'DEF' UNION SELECT 'GHI' UNION SELECT 'JKL' SELECT A.Data, B.Data FROM @TABLE_A AS A, @TABLE_B AS B WHERE A.ID = B.ID SELECT A.Data, B.Data FROM @TABLE_A AS A INNER JOIN @TABLE_B AS B ON A.ID = B.ID 

Ora ometterò il piano per la variabile table create, il piano per entrambe le query è identico però:

  SELECT A.Data, B.Data FROM @TABLE_A AS A, @TABLE_B AS B WHERE A.ID = B.ID |--Nested Loops(Inner Join, OUTER REFERENCES:([A].[ID])) |--Clustered Index Scan(OBJECT:(@TABLE_A AS [A])) |--Clustered Index Seek(OBJECT:(@TABLE_B AS [B]), SEEK:([B].[ID][email protected]_A.[ID] as [A].[ID]) ORDERED FORWARD) SELECT A.Data, B.Data FROM @TABLE_A AS A INNER JOIN @TABLE_B AS B ON A.ID = B.ID |--Nested Loops(Inner Join, OUTER REFERENCES:([A].[ID])) |--Clustered Index Scan(OBJECT:(@TABLE_A AS [A])) |--Clustered Index Seek(OBJECT:(@TABLE_B AS [B]), SEEK:([B].[ID][email protected]_A.[ID] as [A].[ID]) ORDERED FORWARD) 

Quindi, risposta breve – Non c’è bisogno di riscrivere, a meno che non passi molto tempo a cercare di leggerli ogni volta che li mantieni?

È più una scelta di syntax. Preferisco raggruppare le mie condizioni di join con i miei join, quindi uso la syntax INNER JOIN

 SELECT a.someRow, b.someRow FROM tableA AS a INNER JOIN tableB AS b ON a.ID = b.ID WHERE b.ID = ? 

(? essere un segnaposto)

Nulla è sbagliato con la syntax nel tuo esempio. La syntax ‘INNER JOIN’ è generalmente definita syntax ‘ANSI’ e viene dopo lo stile illustrato nell’esempio. Esiste per chiarire il tipo / direzione / costituenti del join, ma generalmente non è funzionalmente diverso da quello che hai.

Il supporto per i join “ANSI” è la piattaforma per database, ma in questi giorni è più o meno universale.

Come nota a margine, un’aggiunta con la syntax ‘ANSI’ era il ‘FULL OUTER JOIN’ o ‘FULL JOIN’.

Spero che questo ti aiuti.

In generale:

Utilizzare la parola chiave JOIN per colbind (ad esempio “join”) chiavi primarie e chiavi esterne.

Utilizza la clausola WHERE per limitare il set di risultati ai soli record a cui sei interessato.

L’unico problema che si può presentare è quando si tenta di mescolare il vecchio join “stile virgola” con i join SQL-92 nella stessa query, ad esempio se è necessario un join interno e un altro join esterno.

 SELECT * FROM table1 AS a, table2 AS b LEFT OUTER JOIN table3 AS c ON a.column1 = c.column1 WHERE a.column2 = b.column2; 

Il problema è che i recenti standard SQL dicono che il JOIN viene valutato prima della virgola. Quindi il riferimento a “a” nella clausola ON dà un errore, perché il nome della correlazione non è stato ancora definito come la clausola ON è in fase di valutazione. Questo è un errore molto confuso da ottenere.

La soluzione è non mescolare i due stili di join. È ansible continuare a utilizzare lo stile virgola nel vecchio codice, ma se si scrive una nuova query, convertire tutti i join nello stile SQL-92.

 SELECT * FROM table1 AS a INNER JOIN table2 AS b ON a.column2 = b.column2 LEFT OUTER JOIN table3 AS c ON a.column1 = c.column1; 

Evito i collegamenti impliciti; quando la query è veramente grande, rendono il codice difficile da decifrare

Con join espliciti e buona formattazione, il codice è più leggibile e comprensibile senza bisogno di commenti.

Un’altra cosa da considerare nella vecchia syntax di join è che è molto facile ottenere un join di cartesion accidentalmente poiché non esiste una clausola on. Se la parola chiave Distinct è presente nella query e utilizza i join vecchio stile, convertirlo in un join standard ANSI e verificare se è ancora necessario il distinto. Se si stanno aggiustando join cartesion accidentali in questo modo, è ansible migliorare enormemente le prestazioni riscrivendole per specificare i campi join e join.

Dipende anche dal fatto che tu stia semplicemente facendo interazioni interne in questo modo o anche in outer join. Ad esempio, la syntax MS SQL Server per i join esterni nella clausola WHERE (= * e * =) può fornire risultati diversi rispetto alla syntax OUTER JOIN e non è più supportata ( http://msdn.microsoft.com/en-us /library/ms178653(SQL.90).aspx ) in SQL Server 2005.