A variável de status do MySQL Handler_read_rnd_next está crescendo muito

11

No status MYSQL, o valor Handler_read_rnd_next é muito alto.

Estou ciente de que esse valor será incrementado quando uma consulta for executada e não tiver índices adequados.

Mas, mesmo quando executamos o status do programa como 'Handler_read_rnd_next', esse valor está sendo incrementado em 2.

Com base nesse sinalizador de status, estamos monitorando algumas estatísticas.

Então, toda vez, essas estatísticas são críticas.

Podemos excluir essas contagens de execução 'show' da contagem de 'Handler_read_rnd_next'.

Mais um exemplo para isso,

Existe uma tabela com 10 linhas, a tabela é indexada na coluna 'data' e, se executarmos a seguinte consulta:

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

e se verificarmos o valor de 'Handler_read_rnd_next', ele será incrementado em 7.

A seguir está o resultado do comando de explicação para a consulta acima:

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 alguma maneira de restringir esse valor, ou posso saber por que esse valor está sendo incrementado muito rapidamente.

Phanindra
fonte
Isso realmente está causando um problema de desempenho?
Aaron Brown # 13
Nenhum desempenho não está sendo afetado, mas a ferramenta de monitoramento está verificando esse sinalizador e mostrando-se crítica.
Phanindra
Se o desempenho não for um problema, corrija a ferramenta de monitoramento.
Aaron Brown #
Eu tinha verificado com outras ferramentas também (Monyog), também há o mesmo problema.
Phanindra
E daí? Ignore-o se não estiver causando um problema de desempenho. É apenas um balcão.
Aaron Brown

Respostas:

5

Antes de tudo, vejamos a definição de Handler_read_rnd_next.

De acordo com a documentação do MySQL em Handler_read_rnd_next:

O número de solicitações para ler a próxima linha no arquivo de dados. Esse valor é alto se você estiver fazendo muitas varreduras de tabela. Geralmente, isso sugere que suas tabelas não são indexadas corretamente ou que suas consultas não são gravadas para aproveitar os índices que você possui.

Agora, olhe sua consulta:

select data from test where data = 'vwx';

Você disse que a tabela tem 10 linhas. Como regra geral, o MySQL Query Optimizer descartará o uso de um índice se o número de linhas que precisam ser examinadas for maior que 5% do número total de linhas.

Vamos fazer as contas. 5% de 10 linhas são 0,5 linhas. Mesmo que o número de linhas precise localizar seus dados seja 1, seja maior que 0,5. Com base nesse menor número de linhas e na regra de índice que acabei de mencionar, o MySQL Query Optimizer sempre fará uma varredura de tabela.

Como a coluna dataé indexada, em vez de uma varredura de tabela, o mysql realizou uma varredura de índice.

Se você tiver certeza de que a tabela de teste nunca crescerá, poderá remover todos os índices e permitir que as verificações da tabela aconteçam. As variáveis ​​de status do manipulador devem parar de aumentar.

RolandoMySQLDBA
fonte
Oi, obrigado pela resposta. Eu tentei remover o índice e verifiquei o valor executando a consulta. Mas o valor de Handler_read_rnd_next está aumentando em 18, que foi incrementado em 7 com o índice. A tabela que eu mencionei não é fixa. Por exemplo, inseri mais 70 linhas na tabela, portanto, o total de linhas é 80 e executei a mesma consulta com o índice na coluna 'data', que ainda retorna apenas uma linha. Mas ainda assim, quando eu checo o valor de 'Handler_read_rnd_next', ele ainda aumenta em 7. Posso saber o motivo pelo qual esse sinalizador é incrementado e como restringir isso.
Phanindra
As mesmas razões que dei ainda se aplicam. Uma verificação de índice foi realizada. Desta vez, não era necessário um índice completo. Evidentemente, sete nós de folhas no BTREE do índice tiveram que ser percorridos para obter a única linha. Os contadores de status do manipulador revelam o uso do índice. A única maneira de restringir é remover o índice completamente, como afirmei. Caso contrário, esse é sempre um comportamento esperado. Melhor indexação de estruturas de tabela mais complexas e consultas projetadas adequadamente pode reduzir a contagem de manipuladores, mas nunca pode removê-las completamente.
RolandoMySQLDBA
"Como regra geral, o MySQL Query Optimizer descartará o uso de um índice se o número de linhas que precisam ser examinadas for maior que 5% do número total de linhas." - isso é muito, muito útil saber. Existe alguma documentação oficial que suporte isso? Muito obrigado!
Itoctopus
2

Qual versão do MySQL?

As razões pelas quais esse sinalizador é incrementado estão melhor documentadas aqui: http://www.mysqlperformanceblog.com/2010/06/15/what-does-handler_read_rnd-mean/

Em resumo, é apenas o contador do número de linhas buscadas em ordem durante uma verificação de tabela completa ou parcial.

Agora, dito isso, estou obtendo um 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
fonte
0

Se houver um índice Exclusivo / primário na coluna "dados", você já fez a otimização para esta consulta. Não consigo pensar em mais otimizações sobre isso.

Além disso, você pode verificar se a verificação de tabela completa foi feita ou não?

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

Certifique-se de que select_scan não tenha aumentado seu valor; dessa maneira, você pode verificar se a verificação de tabela completa está concluída ou não. Tente otimizar uma consulta que não fará a verificação de tabela completa.

Mahesh Patil
fonte