La variable de estado MySQL Handler_read_rnd_next está creciendo mucho

11

En el estado MYSQL, el valor Handler_read_rnd_next es muy alto.

Soy consciente de que este valor se incrementará cuando se ejecute una consulta que no tenga los índices adecuados.

Pero, incluso cuando ejecutamos el estado del show como 'Handler_read_rnd_next', este valor se incrementa en 2.

Según este indicador de estado, estamos monitoreando algunas estadísticas.

Así que cada vez, estas estadísticas se muestran críticas.

¿Podemos excluir estos recuentos de ejecución 'show' del recuento 'Handler_read_rnd_next'?

Un ejemplo más de esto,

Hay una tabla con 10 filas, la tabla está indexada en la columna 'datos', y si ejecutamos la siguiente consulta:

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

y si verificamos el valor de 'Handler_read_rnd_next', se incrementará en 7.

El siguiente es el resultado del comando de explicación para la consulta anterior:

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'

¿Hay alguna forma de restringir este valor o puedo saber por qué este valor se incrementa muy rápido?

Phanindra
fuente
¿Esto realmente está causando un problema de rendimiento?
Aaron Brown
Ningún rendimiento no se ve afectado, pero la herramienta de monitoreo está verificando este indicador y se muestra crítico.
Phanindra
Si el rendimiento no es un problema, repare la herramienta de monitoreo.
Aaron Brown
También había comprobado con otras herramientas (Monyog), también había el mismo problema.
Phanindra
¿Y qué? Ignórelo si no está causando un problema de rendimiento. Es solo un mostrador.
Aaron Brown

Respuestas:

5

En primer lugar, veamos la definición de Handler_read_rnd_next.

De acuerdo con la documentación de MySQL en Handler_read_rnd_next:

El número de solicitudes para leer la siguiente fila en el archivo de datos. Este valor es alto si está haciendo muchos escaneos de tablas. En general, esto sugiere que sus tablas no están indexadas correctamente o que sus consultas no están escritas para aprovechar los índices que tiene.

Ahora, mira tu consulta:

select data from test where data = 'vwx';

Dijiste que la tabla tiene 10 filas. Como regla general, MySQL Query Optimizer descartará el uso de un índice si el número de filas que necesita ser examinado es mayor al 5% del número total de filas.

Hagamos los cálculos. El 5% de 10 filas es 0.5 filas. Incluso si el número de filas necesita ubicar sus datos es 1, eso es mayor que 0.5. Basado en este número menor de filas y la regla de índice que acabo de mencionar, MySQL Query Optimizer siempre hará un escaneo de tabla.

Dado que la columna dataestá indexada, en lugar de un escaneo de tabla, mysql realizó un escaneo de índice.

Si sabe con certeza que la tabla de prueba nunca crecerá, puede eliminar todos los índices y permitir que se realicen escaneos de la tabla. Las variables de estado del controlador deberían dejar de aumentar.

RolandoMySQLDBA
fuente
Hola, gracias por la respuesta. Lo intenté eliminando el índice y verifiqué el valor ejecutando la consulta. Pero el valor de Handler_read_rnd_next se incrementa en 18, que se incrementa en 7 con el índice. La tabla que mencioné no es fija. Ese es un ejemplo, inserté 70 filas más en la tabla, por lo que el total de filas es 80 y ejecuté la misma consulta con el índice en la columna 'datos' que todavía devuelve solo una fila. Pero aún cuando verifico el valor de 'Handler_read_rnd_next', todavía se incrementa en 7. ¿Puedo saber la razón por la cual este indicador se incrementa y cómo restringirlo?
Phanindra
Las mismas razones que di todavía siguen vigentes. Se realizó una exploración de índice. Esta vez, no se necesitaba un índice completo. Evidentemente, 7 nodos de hoja en el BTREE del índice tuvieron que atravesarse para obtener una fila. Los contadores de estado del controlador revelan el uso del índice. La única forma de restringir es eliminar el índice por completo como dije. De lo contrario, este es siempre un comportamiento esperado. Una mejor indexación de estructuras de tabla más complejas y consultas diseñadas adecuadamente pueden mitigar el conteo de manejadores, pero nunca pueden eliminarlos por completo.
RolandoMySQLDBA
"Como regla general, MySQL Query Optimizer descartará el uso de un índice si el número de filas que necesita ser examinado es mayor al 5% del número total de filas". - Esto es muy, muy útil saberlo. ¿Existe alguna documentación oficial que respalde esto? Muchas gracias!
itoctopus
2

¿Qué versión de MySQL?

Las razones por las que este indicador se incrementa se documenta mejor aquí: http://www.mysqlperformanceblog.com/2010/06/15/what-does-handler_read_rnd-mean/

En resumen, es solo el contador del número de filas obtenidas en orden durante un escaneo de tabla completo o parcial.

Ahora, dicho eso, estoy obteniendo un resultado diferente:

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
fuente
0

Si hay un índice único / primario en la columna "datos", entonces ya ha realizado la optimización para esta consulta. No puedo pensar que se pueda hacer una mayor optimización en esto.

¿También puede verificar si se ha realizado un ESCANEO DE TABLA COMPLETA o no?

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

Asegúrese de que select_scan no haya aumentado su valor, de esta manera puede verificar si se ha realizado o no la EXPLORACIÓN DE TABLA COMPLETA. Debe intentar optimizar una consulta que no realice la EXPLORACIÓN DE TABLA COMPLETA.

Mahesh Patil
fuente