2010-06-13 2 views
8

Ho 2 tabelle:2 Seleziona o 1 Accedi alla query?

libro (id, titolo, età) ----> 100 Milioni di righe

autore (id, libro_id, nome, nato) ----> 10 milioni di righe

Ora, supponiamo di avere un ID generico di un libro. Ho bisogno di stampare questa pagina:

Title: mybook 

authors: Tom, Graham, Luis, Clarke, George 

Quindi ... qual è il modo migliore per farlo?

1) Semplice uniscono in questo modo:

Select book.title, author.name 
From book, author 
WHERE (author.book_id = book.id) AND (book.id = 342) 

2) Per evitare il join, ho potuto fare 2 semplice query:

Select title FROM book WHERE id = 342 

Select name FROM author WHERE book_id = 342 

Qual è il modo più efficiente?

risposta

8

Il primo. È solo un viaggio di andata e ritorno. Richiede un po 'di elaborazione per comprimere le righe di autori in una lista separata da virgole come vuoi, ma è fondamentalmente un codice boilerplate.

Separate query correlate sono una cattiva abitudine che ucciderà le tue prestazioni più velocemente della maggior parte delle cose.

+0

Il DB non comprime le righe in un elenco separato da virgole, il client presumibilmente con un linguaggio di scripting. –

+1

@Evan - Può fare con GROUP_CONCAT o simile. –

+0

Non ho detto che non si poteva fare. Volevo solo dire che non è stato fatto ed è estraneo alla domanda. –

2

L'opzione migliore è eseguire test di velocità sul proprio server. A seconda della frequenza con cui le diverse tabelle sono accessibili e separate, una potrebbe essere più veloce.

Questo è stato risposto in profondità prima: LEFT JOIN vs. multiple SELECT statements

1

Il primo, e soprattutto se si dispone di un indice su author.book_id. Un indice chiuso sarebbe la cosa migliore se hai un libro con molti autori ed è possibile, altrimenti anche un non-chiuso ti aiuterà molto.

0

So che non dovrebbe essere una considerazione, ma la prima query restituirà un set di risultati come questo:

title  name 
----------------- 
mybook Tom 
mybook Graham 
mybook Luis 
mybook Clarke 
mybook George 

mentre la seconda coppia restituirà un paio di set di risultati come questo:

title 
------- 
mybook 

e

name 
-------- 
Tom 
Graham 
Luis 
Clarke 
George 

così ogni approccio restituisce i dati in un modo diverso. In questo semplice esempio, la ripetizione del titolo del libro non sarà significativa, ma se al posto del titolo si restituisse il primo capitolo (per esempio), ciò sarebbe meno efficace dato che ci sarebbero molti dati ripetuti. Pertanto, mentre il secondo potrebbe impiegare più tempo nel database, potrebbe essere più veloce e più efficiente quando si inviano tali dati attraverso la rete.

È necessario testare i risultati effettivi e vedere quale si comporta meglio.

+0

sì lo so ... ma voglio sapere qual è il modo più efficiente :) – xRobot

+1

Si potrebbe anche se VI o Emacs è meglio. Non esiste una risposta "corretta" per tutte le situazioni. Esegui centinaia o migliaia di query di prova utilizzando i loop e scopri cosa richiede più tempo. L'uso l'altro. –

+0

@ Aaron, buona analogia. – ChrisF

1

La minimizzazione del giro di andata e la promozione di piani di esecuzione equilibrati sono gli elementi più salienti della mia lista di prestazioni.

Se si dispone di una situazione con dipendenze statiche tra i campi in una query che impedisce all'ottimizzatore di utilizzare un indice, suddividerlo in query separate può fornire enormi vantaggi in termini di prestazioni man mano che gli indici vengono utilizzati e il conteggio delle righe del set di dati aumenta. Per la maggior parte dei protocolli di trasporto del database, ulteriori risultati corrispondono a round trip aggiuntivi. Questo può potenzialmente avere implicazioni sulle prestazioni se i dati vengono regolarmente consultati su una WAN. Fortunatamente ci sono modi per avere la botte piena e la moglie ubriaca:

Select title,NULL AS name FROM book WHERE id = 342 
UNION ALL 
Select NULL,name FROM author WHERE book_id = 342 

Nel tuo esempio speciali Io sceglierei 1 # con un avvertimento a considerare che cosa accadrebbe se non ci fossero gli autori su file per un determinato libro.