Quelle façon de compter un nombre de lignes devrait être plus rapide dans MySQL?
Ce:
SELECT COUNT(*) FROM ... WHERE ...
Ou, l'alternative:
SELECT 1 FROM ... WHERE ...
// and then count the results with a built-in function, e.g. in PHP mysql_num_rows()
On pourrait penser que la première méthode devrait être plus rapide, car il s'agit clairement d'un territoire de base de données et le moteur de base de données devrait être plus rapide que quiconque lors de la détermination de ce genre de choses en interne.
mysql
performance
Franz
la source
la source
SELECT 1
et nonSELECT *
. Y a-t-il une différence?mysql_query()
, par exemple, l'ensemble des résultats est envoyé à PHP depuis MySQL, indépendamment de ce que vous faire avec ces données.Réponses:
Lorsque vous prenez
COUNT(*)
en compte les index de colonne, ce sera le meilleur résultat. Mysql avec le moteur MyISAM stocke en fait le nombre de lignes, il ne compte pas toutes les lignes à chaque fois que vous essayez de compter toutes les lignes. (basé sur la colonne de la clé primaire)Utiliser PHP pour compter les lignes n'est pas très intelligent, car vous devez envoyer des données de mysql vers php. Pourquoi le faire alors que vous pouvez réaliser la même chose du côté mysql?
Si le
COUNT(*)
est lent, vous devez exécuterEXPLAIN
la requête et vérifier si les index sont réellement utilisés et où les ajouter.Ce qui suit n'est pas le moyen le plus rapide , mais il y a un cas où
COUNT(*)
cela ne convient pas vraiment - lorsque vous commencez à regrouper les résultats, vous pouvez rencontrer un problème, oùCOUNT
ne compte pas vraiment toutes les lignes.La solution est
SQL_CALC_FOUND_ROWS
. Ceci est généralement utilisé lorsque vous sélectionnez des lignes mais que vous avez toujours besoin de connaître le nombre total de lignes (par exemple, pour la pagination). Lorsque vous sélectionnez des lignes de données, ajoutez simplement leSQL_CALC_FOUND_ROWS
mot - clé après SELECT:Une fois que vous avez sélectionné les lignes nécessaires, vous pouvez obtenir le nombre avec cette seule requête:
FOUND_ROWS()
doit être appelé immédiatement après la requête de sélection des données.En conclusion, tout se résume en fait au nombre d'entrées que vous avez et au contenu de l'instruction WHERE. Vous devez vraiment faire attention à la façon dont les index sont utilisés, lorsqu'il y a beaucoup de lignes (des dizaines de milliers, des millions et plus).
la source
MyISAM
enregistre le nombre de lignes. D'autres moteurs de stockage commeInnoDB
ne stockent pas le nombre de lignes et compteront toutes les lignes à chaque fois .SELECT 1 FROM ... LIMIT 1
ouSELECT COUNT(*) FROM ...
?WHERE
article.SELECT COUNT(*) FROM ...
peut prendre un temps considérable, en fonction de ce qui doit être analysé (par exemple, une très grande table ou un index de millions / milliards / billion de lignes).SELECT 1 FROM ... LIMIT 1
retourne immédiatement car vous le limitez à la première ligne.Après avoir discuté avec mes coéquipiers, Ricardo nous a dit que le moyen le plus rapide était:
Mais vous devez vous rappeler que le résultat peut ne pas être exact.
Vous pouvez également l'utiliser à partir de la ligne de commande:
Plus d'informations: http://dev.mysql.com/doc/refman/5.7/en/show-table-status.html
Et vous pouvez trouver une discussion complète sur mysqlperformanceblog
la source
SHOW TABLE STATUS
(ou l'équivalentSELECT
dansinformation_schema
) est rapide, mais ne gère pas deWHERE
clause. Il est précis pour MyISAM, mais imprécis (parfois décalé d'un facteur 2) pour InnoDB.Excellente question, bonnes réponses. Voici un moyen rapide de faire écho aux résultats si quelqu'un lit cette page et manque cette partie:
la source
as count
?id
est déroutant au premier regard.Cette requête (qui est similaire à ce que bayuah a posté ) montre un joli résumé de tous les comptes de tables dans une base de données: (version simplifiée de la procédure stockée par Ivan Cachicatari que je recommande vivement).
Exemple:
la source
information_schema
n'est pas la même que celle renvoyée parSELECT count(*) FROM
au cas où InnoDB est utilisé. Si vous avez besoin d'une valeur stricte, gardez à l'esprit que cette méthode donne une valeur stricte uniquement avec les tables MyISAM. Avec InnoDB, le nombre de lignes est une approximation approximative.J'ai toujours compris que ce qui suit me donnera les temps de réponse les plus rapides.
la source
SELECT 1 ...
retournera autant de lignes que leWHERE
etLIMIT
demandera, et elles seront toutes "1".show table status like '<TABLE NAME>'
Ce sera beaucoup plus rapide.WHERE
clause. Et, pour InnoDB, ce n'est qu'une estimation.Si vous avez besoin d'obtenir le nombre de l'ensemble de résultats, vous pouvez adopter l'approche suivante:
Ce n'est normalement pas plus rapide que l'utilisation,
COUNT
bien que l'on puisse penser que le contraire est le cas, car il fait le calcul en interne et ne renvoie pas les données à l'utilisateur, donc l'amélioration des performances est suspectée.Faire ces deux requêtes est bon pour la pagination pour obtenir des totaux mais pas particulièrement pour utiliser des
WHERE
clauses.la source
J'ai fait quelques benchmarks pour comparer le temps d'exécution de
COUNT(*)
vsCOUNT(id)
(id est la clé primaire de la table - indexée).Nombre d'essais: 10 * 1000 requêtes
Résultats:
COUNT(*)
est plus rapide 7%VOIR GRAPHIQUE: benchmarkgraph
Mon conseil est d'utiliser:
SELECT COUNT(*) FROM table
la source
COUNT(1)
, il serait intéressant de voir quelques repères là-bas ...Essaye ça:
la source
select count(*) from table_name
ou autre chose. dba.stackexchange.com/questions/151769/…Vous voudrez peut-être envisager de faire un
SELECT max(Id) - min(Id) + 1
. Cela ne fonctionnera que si vos identifiants sont séquentiels et que les lignes ne sont pas supprimées. C'est cependant très rapide.la source
EXPLAIN SELECT id FROM ....
a fait l'affaire pour moi. et je pouvais voir le nombre de lignes sous larows
colonne du résultat.la source
J'ai manipulé des tables pour le gouvernement allemand avec parfois 60 millions d'enregistrements.
Et nous devions connaître plusieurs fois le nombre total de lignes.
Ainsi, nous, les programmeurs de bases de données, avons décidé que dans chaque table se trouve l'enregistrement un toujours l'enregistrement dans lequel le nombre total d'enregistrements est stocké. Nous avons mis à jour ce nombre, en fonction des lignes INSERT ou DELETE.
Nous avons essayé toutes les autres méthodes. C'est de loin le moyen le plus rapide.
la source
Une instruction count (*) avec une condition where sur la clé primaire a renvoyé le nombre de lignes beaucoup plus rapidement pour moi, évitant ainsi une analyse complète de la table.
C'était beaucoup plus rapide pour moi que
la source