2013-03-14 16 views
5

La tabella si trova nella tabella InnoDB. Ecco alcune informazioni che potrebbero essere utili.Query MySQL molto lenta. Conteggio (*) nella colonna indicizzata

EXPLAIN SELECT COUNT(*) AS y0_ FROM db.table this_ WHERE this_.id IS NOT NULL; 

+----+-------------+-------+-------+---------------+---------+---------+------+---------+--------------------------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref | rows | Extra     | 
+----+-------------+-------+-------+---------------+---------+---------+------+---------+--------------------------+ 
| 1 | SIMPLE  | this_ | index | PRIMARY  | PRIMARY | 8  | NULL | 4711235 | Using where; Using index | 
+----+-------------+-------+-------+---------------+---------+---------+------+---------+--------------------------+ 
1 row in set (0.00 sec) 

mysql> DESCRIBE db.table; 
+--------------+--------------+------+-----+---------+-------+ 
| Field  | Type   | Null | Key | Default | Extra | 
+--------------+--------------+------+-----+---------+-------+ 
| id   | bigint(20) | NO | PRI | NULL |  | 
| id2   | varchar(28) | YES |  | NULL |  | 
| photo  | longblob  | YES |  | NULL |  | 
| source  | varchar(10) | YES |  | NULL |  | 
| file_name | varchar(120) | YES |  | NULL |  | 
| file_type | char(1)  | YES |  | NULL |  | 
| created_date | datetime  | YES |  | NULL |  | 
| updated_date | datetime  | YES |  | NULL |  | 
| createdby | varchar(50) | YES |  | NULL |  | 
| updatedby | varchar(50) | YES |  | NULL |  | 
+--------------+--------------+------+-----+---------+-------+ 
10 rows in set (0.05 sec) 

La query di spiegazione mi dà il risultato proprio lì. Ma la query effettiva è in esecuzione da un po 'di tempo. Come posso risolvere questo? Che cosa sto facendo di sbagliato?

Fondamentalmente ho bisogno di capire quanti photos ci sono in questa tabella. Inizialmente il codificatore originale aveva una query che controllava WHERE photo IS NOT NULL (che richiedeva 3 ore +) ma ho modificato questa query per controllare la colonna id in quanto è una chiave primaria. Mi aspettavo un enorme guadagno in termini di prestazioni e mi aspettavo una risposta in meno di un secondo, ma questo sembra non essere il caso.

Che tipo di ottimizzazioni sul database devo fare? Penso che la query sia soddisfacente, ma sentitevi liberi di correggermi se sbaglio.

Edit: mysql Ver 14.14 Distrib 5.1.52, per redhat-linux-gnu (x86_64) utilizzando readline 5.1

P.S: ho rinominato i tavoli per qualche ragione folle. In realtà non ho il database chiamato db e la tabella in questione denominata table.

+0

Come funziona 'SELECT COUNT (*) FROM db.table'? (Poiché 'id' non è nullo, equivale alla tua query corrente.) – ruakh

+0

Bad. Ci vogliono più di 10 minuti (non posso dirlo con certezza, ma per quanto tempo ho aspettato). – Sanchit

risposta

9

Quanto è "lungo"? Quante righe ci sono in questa tabella?

Una tabella MyISAM tiene traccia di quante righe ha, quindi un semplice COUNT (*) tornerà sempre quasi istantaneamente.

InnoDB, d'altra parte funziona in modo diverso: una tabella InnoDB non tiene traccia di quante righe ha, quindi quando COUNT (*), deve letteralmente andare e contare ogni riga. Se hai una tabella grande, questo può richiedere un numero di secondi.

MODIFICA: provare COUNT(ID) anziché COUNT(*), dove ID è una colonna indicizzata che non contiene NULL. Il potrebbe eseguire più veloce.

EDIT2: Se si memorizzano i dati binari dei file nella longblob, la tabella sarà massiccia, il che rallenterà le cose.

Possibili soluzioni:

  1. Uso MyISAM, invece di InnoDB.
  2. Mantenere il proprio conteggio, magari utilizzando i trigger sugli inserimenti e le eliminazioni.
  3. Estrarre i dati binari in un'altra tabella, preferibilmente file regolari.
+0

Per quanto tempo InnoDB dovrebbe assumere una tabella di 4,7 milioni di righe? La dichiarazione spiega mi dà la mia risposta in meno di un secondo! – Sanchit

+0

Sì, è solo una stima! http://dev.mysql.com/doc/refman/5.0/en/innodb-restrictions.html – aidan

+0

Non sono sicuro di quanto durerà una query di conteggio su 4.7m righe, perché dipenderà da altre cose come la CPU velocità, carico della CPU, ecc., ma forse 5 secondi? – aidan

Problemi correlati