2012-11-27 7 views
7

Ho la seguente interrogazioneCome migliorare le prestazioni di COUNT (campo DISTINCT1) ... GROUP BY field2?

EXPLAIN SELECT COUNT(DISTINCT ip_address) as ip_address, exec_date 
    FROM requests 
    GROUP BY exec_date; 

id select_type table  type  possible_keys key   key_len ref  rows Extra 
1 SIMPLE  requests range  NULL   daily_ips 263  NULL 488213 Using index for group-by (scanning) 

Con un indice di copertura daily_ips

Table  Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment 
requests 1   daily_ips 1    exec_date A   16   NULL  NULL YES BTREE  
requests 1   daily_ips 2    ip_address A   483492  NULL  NULL YES BTREE  

C'è un modo posso ottimizzare ulteriormente questa ricerca?

Che cosa significa esattamente Using index for group-by (scanning)? Significa che l'intera clausola GROUP BY viene eseguita interamente da un indice mentre la parte COUNT(DISTINCT ip_address) dell'istruzione non è?

risposta

3

In base ai dati forniti, non vedo alcun modo per ottimizzare ulteriormente la query.

Per quanto riguarda la tua domanda di follow-up, pagina di manuale di MySQL che descrive spiegare output per Using index for group-by dice:

Simile al metodo di accesso tabella indice Utilizzando, utilizzando l'indice per il gruppo-by indica che MySQL ha trovato un indice che può essere utilizzato per recuperare tutte le colonne di una query GROUP BY o DISTINCT senza alcun accesso al disco aggiuntivo alla tabella effettiva. Inoltre, l'indice viene utilizzato nel modo più efficiente in modo che per ogni gruppo vengano lette solo alcune voci dell'indice. Per dettagli, vedere Section 8.13.10, “GROUP BY Optimization”.

L'indice è particolarmente adatto per velocizzare la ricerca. Poiché vengono selezionati solo i campi indicizzati (ogni colonna della query viene visualizzata anche nell'indice), MySQL potrebbe non avere nemmeno bisogno di colpire la tabella, poiché tutti i dati rilevanti vengono visualizzati nell'indice.

Se l'esecuzione di una query era come eseguire una ricerca su google, immagina di non dover fare clic su alcuno dei siti collegati, perché hai trovato le informazioni che stavi cercando direttamente nei risultati della ricerca - è un po 'come cosa no è necessario analizzare i dati della tabella. Ecco ulteriori informazioni su how MySQL uses indexes:

In alcuni casi, una query può essere ottimizzata per recuperare i valori senza consultare le righe di dati. (Un indice che fornisce tutti i risultati necessari per una query è denominato covering index.) Se una query utilizza solo colonne da una tabella numerica e che formano il prefisso più a sinistra per una determinata chiave, i valori selezionati possono essere recuperati dall'albero dell'indice per una maggiore velocità:

SELEZIONAkey_part3dAnome_tabellaDOVEkey_part1 = 1

+1

Grazie Danny, per curiosità c'è un modo per capire se "L'uso dell'indice per raggruppamento (scansione)" si riferisce all'indice applicato alla clausola 'GROUP-BY' o' DISTINCT'? – user784637

+0

Poiché 'DISTINCT' è solo [un caso speciale di' GROUP BY'] (http://dev.mysql.com/doc/refman/5.0/en/distinct-optimization.html), e poiché entrambe le colonne provengono dal stesso tavolo, lo stesso indice, onestamente non sono sicuro. –

0

È puoi Objectify:

Objectify ofy = ObjectifyService.begin(); Query query = ofy.query (ecco la classe name.class) .filter ("nome colonna nella tabella", valore per cui eseguire una query) .list();

Prima di ciò potrebbe essere necessario aggiungere il barattolo per Objectify.