2012-06-05 14 views
6

ho due tabelle:Quando è meglio non usare inner join?

table1 (id, name, connte) 
table2 (id, name, connte) 

sono collegati tramite table1.connte e table2.connte. E ognuno di loro contiene 100 record.

Ora, se voglio eliminare un record da table1 con id = 20 e dei suoi figli corrispondenti table2, è meglio effettuare le seguenti operazioni:

DELETE d1,d2 FROM table1 d1 INNER JOIN table2 d2 ON d1.connte= d2.connte WHERE d1.id = 20 

o il seguente:

select connte from table1 where id = 20 
    --Store connte in a variable say aabc-- 
    delete from table2 where connte = aabc -> execute this first 
    delete from table1 where id = 20 -> execute this second 

Se c'è un solo genitore e un figlio per un record che voglio cancellare (qui table1.id = 20), allora non è costoso fare inner join per l'intera tabella?

Sto eseguendo questa query da JAVA (quindi JDBC), quindi è più costoso (prestazioni saggio) eseguire più query o un join interno, per la condizione sopra menzionata?

NOTA: Assunzione di integrità referenziale per le tabelle. Quindi, non sto usando l'eliminazione a cascata.

risposta

6

Probabilmente sarà più veloce farlo in una query anziché in due. In pratica stai provando a fare delle ottimizzazioni invece di lasciare che sia il DBMS a farlo, e generalmente i DBMS sono davvero bravi in ​​questo genere di cose.

Inoltre, probabilmente non dovrai preoccuparti di eliminare le prestazioni per le tabelle così piccole. 100 x 100 righe è ancora molto piccolo, quindi il tuo DBMS dovrebbe essere in grado di gestirlo senza problemi.

+0

Hmm..ok, ma che dire di quando ho, diciamo centomila o un milione di record? Quale approccio sarebbe quindi migliore per la mia condizione menzionata? – Harke

+0

Vorrei ancora raccomandare che il DBMS lo gestisca. Sa come fare queste ottimizzazioni meglio di quanto tu possa. – Oleksi

+0

C'è un modo per sapere come funziona l'inner join? Non si uniranno due tavoli con milioni di record ciascuno, ci vorrà del tempo? (anche dopo aver filtrato con la clausola ON, c'è la possibilità che ci siano molti record da unire) – Harke

3

Il modo migliore per eseguire questa operazione è eseguire un piano di spiegazione su entrambe le query nel DBMS e l'output fornisce elementi come stime I/O, ecc. In generale, ogni volta che si ha una domanda su cosa sarà più efficiente dal punto di vista del DBMS, esaminare i piani di query e le stime dei costi è la tua arma migliore.

SET showplan on 

dovrebbe funzionare nel server SQL. Ecco lo MSDN documentation, potrebbe essere necessaria una sintassi leggermente diversa a seconda del DBMS. La stima dei costi di I/O è probabilmente ciò che ti interessa di più.

per MySQL, sembra che è possibile utilizzare

EXPLAIN SELECT * FROM some_table 

Here is a tutorial su query che analizzano utilizzando spiegare.

In generale, Oleksi è corretto; la maggior parte degli ottimizzatori è molto brava in questo genere di cose e creare manualmente un tavolo temporaneo non ti comprerà molto. Molte volte il piano di query dell'ottimizzatore prevede la creazione di una tabella temporanea.

Per una query di eliminazione, una cosa importante per garantire la velocità è che la clausola di eliminazione utilizza parametri indicizzati, pertanto non provoca una scansione completa della tabella. Spiega/Showplan ti dirà che tipo di scansione sta facendo la tua query e quali indici sta usando. In genere si desidera evitare scansioni complete della tabella.

1

In Sql Server non è possibile eliminare da due tabelle in un'unica istruzione di eliminazione (senza trigger o eliminazione a cascata).

+0

Quindi, nel mio caso (che non ha integrità referenziale e nessun trigger), è possibile solo la seconda condizione? – Harke

+0

sì, per il server SQl, Mysql potrebbe essere diverso – HLGEM

0

Perché non considerare l'utilizzo di chiavi esterne e cancellazioni a cascata? Se imposti correttamente il tuo tavolo, dovrai semplicemente cancellare il genitore e il bambino verrà automaticamente preso in carico. Vedere questo link When/Why to use Cascading in SQL Server?