web-dev-qa-db-fra.com

Pourquoi le décompte (*) est-il lent, alors que expliquer connaît la réponse?

Cette requête: select count(*) from planner_event prend très longtemps à s'exécuter - si longtemps, j'ai abandonné et je l'ai tuée avant la fin. Cependant, lorsque j'exécute explain select count(*) from planner_event, je peux voir une colonne dans la sortie avec le nombre de lignes (14m).

Pourquoi expliquer peut-il obtenir le nombre de lignes instantanément, mais compter (*) prend beaucoup de temps à s'exécuter?

14
Benubird

Explain utilise des statistiques précédemment collectées (utilisées par l'optimiseur de requêtes). Faire une select count(*) lit CHAQUE bloc de données.

Voici un moyen peu coûteux d'obtenir un nombre de lignes estimé:

select TABLE_ROWS FROM INFORMATION_SCHEMA.TABLES where TABLE_NAME='planner_event';

Même si vous avez fait select count(id), cela peut encore prendre beaucoup de temps, sauf si vous avez un index secondaire sur id (en supposant également que id est une CLÉ PRIMAIRE). Étant donné que toutes les données (y compris les données de ligne) sont stockées dans des index B-Tree, effectuer une select count(PK_COLUMN) est toujours une quantité considérable de IO (doit lire toutes les pages de données). Si vous avez un index secondaire sur le champ PK, il pourra effectuer moins IO pour effectuer un comptage.

16
Kevin Bott

Explain obtient le nombre de certaines "statistiques" qui sont utilisées pour estimer les choses pour l'Optimizer. Ce nombre peut être loin d'être correct - je le vois parfois être plus d'un facteur 2 (supérieur ou inférieur) à la valeur exacte.

L'exécution de la COUNT(*) sur une table InnoDB doit analyser la table pour éviter les enregistrements de comptage incorrect qui sont insérés/supprimés par d'autres connexions mais pas encore "validés". En fait, il suffit de faire une analyse complète sur certains index, pas nécessairement sur toute la table (qui contient le PRIMARY KEY).

Combien RAM avez-vous? Quelle est la valeur de innodb_buffer_pool_size? Cela pourrait être utile s'il s'agissait d'environ 70% de RAM.

3
Rick James