La variable d'état MySQL Handler_read_rnd_next grandit beaucoup

11

Dans l'état MYSQL, la valeur Handler_read_rnd_next est très élevée.

Je suis conscient que cette valeur sera incrémentée lorsqu'une requête est exécutée qui n'a pas d'index appropriés.

Mais, même lorsque nous exécutons l'état d'affichage comme «Handler_read_rnd_next», cette valeur est incrémentée de 2.

Sur la base de cet indicateur de statut, nous surveillons certaines statistiques.

Donc, à chaque fois, ces statistiques sont critiques.

Pouvons-nous exclure ces décomptes d'exécution «show» du décompte «Handler_read_rnd_next».

Un autre exemple pour cela,

Il y a une table avec 10 lignes, la table est indexée sur la colonne 'data', et si nous exécutons la requête suivante:

select data from test where data = 'vwx' -> returns one row

et si nous vérifions la valeur de 'Handler_read_rnd_next', elle est incrémentée de 7.

Voici le résultat de la commande d'explication pour la requête ci-dessus:

explain select data from test where data = 'vwx';

id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra

1, 'SIMPLE', 'test', 'ref', 'data', 'data', '35', 'const', 1, 'Using where; Using index'

Existe-t-il un moyen de restreindre cette valeur, ou puis-je savoir pourquoi cette valeur est incrémentée très rapidement.

Phanindra
la source
Est-ce que cela cause réellement un problème de performances?
Aaron Brown
Aucune performance n'est affectée, mais l'outil de surveillance vérifie cet indicateur et affiche un niveau critique.
Phanindra
Si les performances ne sont pas un problème, corrigez plutôt l'outil de surveillance.
Aaron Brown
J'avais aussi vérifié avec d'autres outils (Monyog), il y avait aussi le même problème.
Phanindra
et alors? Ignorez-le s'il ne cause pas de problème de performances. C'est juste un compteur.
Aaron Brown

Réponses:

5

Tout d'abord, regardons la définition de Handler_read_rnd_next.

Selon la documentation MySQL sur Handler_read_rnd_next:

Nombre de demandes de lecture de la ligne suivante dans le fichier de données. Cette valeur est élevée si vous effectuez de nombreuses analyses de table. En général, cela suggère que vos tables ne sont pas correctement indexées ou que vos requêtes ne sont pas écrites pour tirer parti des index dont vous disposez.

Maintenant, regardez votre requête:

select data from test where data = 'vwx';

Vous avez dit que le tableau comporte 10 lignes. En règle générale, l'optimiseur de requêtes MySQL rejettera l'utilisation d'un index si le nombre de lignes à examiner est supérieur à 5% du nombre total de lignes.

Faisons le calcul. 5% de 10 lignes correspondent à 0,5 ligne. Même si le nombre de lignes nécessaires pour localiser vos données est 1, il est supérieur à 0,5. Sur la base de ce nombre inférieur de lignes et de la règle d'index que je viens de mentionner, MySQL Query Optimizer effectuera toujours une analyse de table.

Puisque la colonne dataest elle-même indexée, au lieu d'un scan de table, mysql a été effectué un scan d'index.

Si vous savez avec certitude que la table de test ne se développera jamais, vous pouvez supprimer tous les index et laisser les analyses de table se produire. Les variables d'état du gestionnaire doivent cesser d'incrémenter.

RolandoMySQLDBA
la source
Salut, merci pour la réponse. J'avais essayé en supprimant l'index et vérifié la valeur en exécutant la requête. Mais la valeur de Handler_read_rnd_next est incrémentée de 18 qui incrémentait de 7 avec index. Le tableau que j'ai mentionné n'est pas fixe. C'est un exemple, j'ai inséré 70 lignes de plus dans la table, donc le nombre total de lignes est de 80 et j'ai exécuté la même requête avec index sur la colonne 'data' qui ne renvoie toujours qu'une seule ligne. Mais quand je vérifie la valeur de 'Handler_read_rnd_next', il incrémente toujours de 7. Puis-je savoir la raison pour laquelle cet indicateur est incrémenté et comment restreindre cela.
Phanindra
Les mêmes raisons exactes que j'ai données s'appliquent toujours. Une analyse d'index a été effectuée. Cette fois, un index complet n'était pas nécessaire. De toute évidence, 7 nœuds foliaires dans la BTREE de l'index ont dû être traversés pour obtenir la première ligne. Les compteurs d'état du gestionnaire révèlent l'utilisation de l'index. La seule façon de restreindre est de supprimer complètement l'index comme je l'ai dit. Sinon, il s'agit toujours d'un comportement attendu. Un meilleur indexage des structures de table plus complexes et des requêtes correctement conçues peuvent réduire le nombre de gestionnaires mais ne peuvent jamais les supprimer complètement.
RolandoMySQLDBA
"En règle générale, MySQL Query Optimizer rejettera l'utilisation d'un index si le nombre de lignes à examiner est supérieur à 5% du nombre total de lignes." - c'est très très utile de savoir. Existe-t-il une documentation officielle à l'appui de cela? Merci beaucoup!
itoctopus le
2

Quelle version de MySQL?

Les raisons pour lesquelles ce drapeau est incrémenté sont mieux documentées ici: http://www.mysqlperformanceblog.com/2010/06/15/what-does-handler_read_rnd-mean/

En bref, il s'agit simplement du compteur du nombre de lignes extraites dans l'ordre lors d'une analyse complète ou partielle de la table.

Maintenant, cela dit, j'obtiens un résultat différent:

mysql> CREATE TABLE `test` (
    ->   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    ->   `data` varchar(255) NOT NULL,
    ->   PRIMARY KEY (`id`),
    ->   KEY `data` (`data`)
    -> ) ENGINE=InnoDB;
Query OK, 0 rows affected (0.27 sec)

mysql> INSERT INTO test (data) VALUES ('a'), ('b'), ('c'), ('d'), ('e'), ('f'), ('g'), ('h'), ('i'), ('vwx');
Query OK, 10 rows affected (0.06 sec)
Records: 10  Duplicates: 0  Warnings: 0

mysql> FLUSH STATUS;
Query OK, 0 rows affected (0.07 sec)

mysql> select data from test where data = 'vwx';
+------+
| data |
+------+
| vwx  |
+------+
1 row in set (0.04 sec)

mysql> SHOW SESSION STATUS LIKE 'Handler%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Handler_commit             | 1     |
| Handler_delete             | 0     |
| Handler_discover           | 0     |
| Handler_prepare            | 0     |
| Handler_read_first         | 0     |
| Handler_read_key           | 3     |
| Handler_read_last          | 0     |
| Handler_read_next          | 1     |
| Handler_read_prev          | 0     |
| Handler_read_rnd           | 0     |
| Handler_read_rnd_next      | 0     |
| Handler_rollback           | 0     |
| Handler_savepoint          | 0     |
| Handler_savepoint_rollback | 0     |
| Handler_update             | 0     |
| Handler_write              | 0     |
+----------------------------+-------+
16 rows in set (0.15 sec)
RS
la source
0

S'il existe un index Unique / principal sur la colonne "données", vous avez déjà effectué l'optimisation pour cette requête. Je ne peux pas penser qu'une optimisation supplémentaire puisse être faite à ce sujet.

Vous pouvez également vérifier si une analyse complète de la table a été effectuée ou non?

SHOW STATUS like 'select_scan'; 
SELECT data from test where data='vmx';
SHOW STATUS like 'select_scan'; 

Assurez-vous que select_scan n'a pas augmenté sa valeur, de cette façon, vous pouvez vérifier si l'analyse complète de la table est effectuée ou non. Vous devriez essayer d'optimiser une requête qui ne fera pas l'analyse complète de la table.

Mahesh Patil
la source