/ / perché mysql select count (1) richiede così tanto tempo? - mysql, prestazioni del database

perché mysql select count (1) richiede così tanto tempo? - mysql, prestazioni del database

Quando ho iniziato a utilizzare MySQL, a select count(*) o select count(1) era quasi istantaneo. Ma sto usando la versione 5.6.25 ospitata su Dreamhost, e ci vogliono 20-30 secondi, a volte, per fare un select count(1). Tuttavia, la seconda volta è veloce --- come l'indice è memorizzato nella cache --- ma non super veloce, come i dati provengono solo dall'indice dei metadati.

Qualcuno capisce cosa sta succedendo e perché è cambiato?

mysql> select count(1) from times;
+----------+
| count(1) |
+----------+
|  1511553 |
+----------+
1 row in set (22.04 sec)

mysql> select count(1) from times;
+----------+
| count(1) |
+----------+
|  1512007 |
+----------+
1 row in set (0.54 sec)

mysql> select version();
+------------+
| version()  |
+------------+
| 5.6.25-log |
+------------+
1 row in set (0.00 sec)

mysql>

risposte:

4 per risposta № 1

Immagino che quando hai iniziato, hai utilizzato MyISAM e ora stai usando InnoDB. InnoDB non memorizza queste informazioni. Vedi documentazione: Limiti sulle tabelle InnoDB

InnoDB non mantiene un conteggio interno di righe inuna tabella perché le transazioni concorrenti potrebbero "vedere" diversi numeri di righe contemporaneamente. Per elaborare SELECT COUNT (*) FROM t, InnoDB esegue la scansione di un indice della tabella, che richiede un po 'di tempo se l'indice non è interamente nel bufferpool. Per ottenere un conteggio veloce, devi utilizzare un tavolo contatore che crei te stesso e lasciare che la tua applicazione lo aggiorni secondo gli inserti e lo cancelli. Se è sufficiente un conteggio di righe approssimativo, è possibile utilizzare SHOW TABLE STATUS. Vedi Sezione 9.5, "Ottimizzazione per tabelle InnoDB".

Pertanto, quando l'indice è interamente nel pool di buffer dopo la prima query (più lenta), la seconda query è di nuovo rapida.

MyISAM non ha bisogno di preoccuparsi dei problemi che potrebbero creare transazioni concorrenti, perché non supporta le transazioni, e così select count(*) from t cercherà solo e restituirà un valore memorizzato molto velocemente.