2011-08-31 19 views
12

Ho la seguente tabella in un database MySQL:multipla Indice della rubrica vs più indici

CREATE TABLE `secondary_images` (
    `imgId` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `primaryId` int(10) unsigned DEFAULT NULL, 
    `view` varchar(255) DEFAULT NULL, 
    `imgURL` varchar(255) DEFAULT NULL, 
    `imgDate` datetime DEFAULT NULL, 
    PRIMARY KEY (`imgId`), 
    KEY `primaryId` (`primaryId`), 
    KEY `imgDate` (`imgDate`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ; 

Lo SQL sarà il seguente:

SELECT imgURL, view FROM secondary_images 
WHERE primaryId={$imgId} ORDER BY imgDate DESC 

Come potete vedere ho fatto sia il primaryId e imgDate, tasti indice. Il mio pensiero dietro che era perché le WHERE query clausola risultati utilizzando il primaryId, e la clausola ORDER utilizza imgDate.

La mia domanda è, sarebbe meglio usare più indici come sono in questo momento? O dovrei un indice a colonne multiple (qualcosa che non capisco molto bene al momento)?

Questo è quello che ricevo da spiego:

id = 1 
select_type = simple  
table = secondary_images   
type = ref 
possible_keys = primaryId 
key = primaryId 
key_len = 5 
ref = const 
rows = 1 
extra = Using where; Using filesort 

NOTA: Questo non sta usando una colonna multipla Index, è il risultato di usare la descrizione della tabella di cui sopra.

+0

Puoi pubblicare la SPIEGA per la selezione? :) – Konerak

+2

Ricorda che gli indeces non sono gratuiti. Se si hanno più oggetti, cioè su ogni inserto o aggiornamento, ogni indice deve essere aggiornato. È necessario valutare il successo prestazionale di tali aggiornamenti per il miglioramento delle prestazioni che vedrai al momento del recupero. – Marvo

+0

Ricorda inoltre che se hai una colonna con lo stesso valore in molte righe, gli indici potrebbero peggiorare le prestazioni. – Poodlehat

risposta

13

È necessario utilizzare un indice multi-colonna (primaryId, imgDate) in modo che MySQL è in grado di utilizzarlo per selezionare le righe e smistamento.

Se tutte le colonne utilizzate per l'ordinamento non sono nell'indice usato per la selezione, MySQL utilizza la strategia "FileSort", che consiste di classificare tutte le righe (in memoria se non c'è troppa righe; sul disco altro).

Se tutte le colonne utilizzate per l'ordinamento sono nell'indice, MySQL utilizza l'indice per ottenere l'ordine file (con alcune restrizioni).

MySQL utilizza una struttura ad albero per gli indici. Ciò consente di accedere alle chiavi in ​​ordine direttamente senza ordinamento.

Un indice a più colonne è fondamentalmente un indice della concatenazione delle colonne. Ciò consente a MySQL di trovare la prima riga corrispondente allo primaryId={$imgId} e quindi accedere direttamente a tutte le altre righe nell'ordine corretto.

Con un indice a riga singola su primaryId, MySQL può trovare tutte le righe corrispondenti a primaryId={$imgId}, ma troverà le righe in nessun ordine particolare; quindi dovrà ordinarli dopo.

Vedi EXPLAIN e ORDER BY Optimization.

+0

Non capisco perché - sta confrontando una colonna con un'altra, non due colonne contemporaneamente con altre due colonne. Puoi spiegare? – Poodlehat

+0

@ arnaud576875 - Grazie mille! Qualche possibilità potresti darmi una breve spiegazione del perché questa sia la scelta migliore in questa situazione? Inoltre, come farei per cambiare la mia tabella corrente usando 'SQL' per usare un indice multi-colonna su' (primaryId, imgDate) '? – stefmikhail

+0

@Poodlehat, stefmikhail Ho aggiornato la risposta – arnaud576875

11

I suoi spiegare assomiglia a questo:

[id] => 1 
[select_type] => SIMPLE 
[table] => secondary_images 
[type] => ref 
[possible_keys] => primaryId 
[key] => primaryId 
[key_len] => 5 
[ref] => const 
[rows] => 1 
[Extra] => Using where; Using filesort 

Andiamo a piedi attraverso di essa.

[id] => 1 

Significa che stiamo parlando del primo tavolo. Stai solo chiamando una tabella nella tua dichiarazione.

[select_type] => SIMPLE 

Stiamo facendo una semplice SELECT.

[table] => secondary_images 

Nome tabella in questione.

[type] => ref 

Il tipo di selezione, più importante per il join.

[possible_keys] => primaryId 

Questa è un campo importante: mostra quali tasti può eventualmente essere utilizzato per aiutare la query in esecuzione più veloce. In questo caso, solo la tua chiave primaria è ritenuta utile.

[key] => primaryId 

Questa è un campo importante: indica quale tasto (s) infine sono stati utilizzati. In questo caso, la chiave primaria.

[key_len] => 5 
[ref] => const 
[rows] => 1 

Indovina il numero di righe esaminate dalla query.

[Extra] => Using where; Using filesort 

Il più importante campo imho. - Utilizzo di dove: si sta utilizzando un'istruzione where. Abbastanza ok - Uso di filesort: il risultato della tua query è così grande che non può essere ordinato in memoria. MySQL deve scriverlo in un file, ordinare il file e quindi emettere. Ciò significa accesso al disco e rallenterà tutto. Aggiungere un indice che può aiutare l'ordinamento spesso aiuta, ma risolvere "using filesort" è un capitolo a parte.

+0

Wow, wow wow. Grazie mille per quello. Molto più facile da capire. Quindi, come posso usare queste informazioni per decidere se una chiave di indice multipla è la strada da percorrere? Non ti chiederò di entrare nel problema di filesort come tu stesso hai detto che è un altro problema, ma passare a un tasto con più indici può essere d'aiuto? – stefmikhail

+2

Dovresti ** leggere ** prima di spiegare. Il sito MySQL è un ottimo punto di partenza, e 'High Performance MySQL' è il miglior libro MySQL che abbia mai letto. Quindi, capisci che dipende molto dalla tua tabella, dal motore di archiviazione, dalla tua configurazione (dimensioni della cache e così via) e dai dati nella tabella. Quindi, il modo migliore per testare: copiare la tabella e aggiungere l'indice desiderato sulla copia. Quindi, confronta le spiegazioni. Ecco perché è necessario capire spiegare :) – Konerak

+0

Grazie ancora. Molto apprezzato. Prenderò quel libro. – stefmikhail

Problemi correlati