MySQL extremamente lento em consultas SELECT muito simples

10

Temos um aplicativo Web simples rodando em uma máquina virtual que salva seus dados em um banco de dados MySQL 5.5 com o mecanismo InnoDB. Tudo funcionou bem por cerca de três anos, mas de repente ficou extremamente lento.

Por exemplo, eu tenho uma tabela muito simples contendo endereços:

CREATE TABLE `addresses` (
  `address_id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(64) CHARACTER SET latin1 NOT NULL,
  `firstname` varchar(64) CHARACTER SET latin1 NOT NULL,
  `street` varchar(64) CHARACTER SET latin1 NOT NULL,
  `housenumber` varchar(16) CHARACTER SET latin1 NOT NULL,
  `zip` varchar(5) CHARACTER SET latin1 NOT NULL,
  `city` varchar(64) CHARACTER SET latin1 NOT NULL,
  `email` varchar(64) CHARACTER SET latin1 NOT NULL,
  `phone` varchar(16) CHARACTER SET latin1 NOT NULL,
  `birthdate` date NOT NULL,
  PRIMARY KEY (`address_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin

Esta tabela contém cerca de 800 entradas, o que realmente não é muito. Mas executando a consulta

SELECT * FROM addresses

para fins de teste, parece que nunca termina. Eu verifiquei isso com a CLI do mysql no próprio servidor: ele gera algumas linhas da tabela e aguarda muito tempo até gerar as próximas linhas.

Talvez seja um problema na fase de envio de dados, mas não tenho certeza.

A VM possui 2 GB de RAM e apenas 320 MB são usados. A CPU também roda em níveis muito baixos de 1 a 2%. O mytop não mostra outras consultas que estejam bloqueando o servidor. O administrador de TI disse que eles não mudaram nada no lado do hardware.

Eu já tentei algo como reiniciar o servidor de banco de dados, reiniciar a máquina virtual. Nada ajudou.

editar:

EXPLAIN SELECT * FROM addresses

me dá este resultado:

+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
| id | select_type | table     | type | possible_keys | key  | key_len | ref  | rows | Extra |
+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
|  1 | SIMPLE      | addresses | ALL  | NULL          | NULL | NULL    | NULL |  793 |       |
+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
1 row in set (0.00 sec)
tabb
fonte
Virtual Box, Xen ou algo mais? Como é configurado o disco host? existem outras VMs na mesma caixa que estão rodando devagar também? Respondendo a essas perguntas pode revelar a resposta
Matt
Eu não sou o dono do hipervisor, então não posso realmente responder a isso. Eu já perguntei ao administrador do hipervisor se eles sabem de alguma alteração recente, mas ele disse que não.
Tabb
se você puder, desligue o mysql e execute algum benchmark de disco e memória. Não precisa ser complicado. A idéia é apenas isolar se é um problema com o mysql, talvez um problema de índice, conforme indicado na resposta abaixo, ou mais difundido.
Matt
Bom ponto, eu experimentei provavelmente não sendo um problema de mysql. A execução mysql -u username -ppassword mydb -e 'SELECT * FROM addressesé lenta, mas, anexando `> test.txt`, é executada muito rapidamente. Agora isso provavelmente seria uma pergunta diferente !? Como eu pude investigar isso?
Tabb
Entre em contato com o proprietário do hypervisor e solicite a verificação dos logs quanto a erros. Erros de disco especificamente. Diga a ele seus sintomas. Faça backup agora.
Matt

Respostas:

13

Se a carga da CPU for baixa, isso indica que não há problemas com índices ausentes, se esse fosse o caso, a consulta precisaria apenas de mais acesso à CPU e ao disco. Você também disse que funcionou bem por 3 anos.

Você verificou a velocidade geral de acesso ao disco (especificamente na partição em que o banco de dados está localizado)? Por exemplo, usando dd como aqui . O que você está descrevendo parece um disco morto ou um ataque meio morto. Espero ter backups?

user3648611
fonte
Este é um bom ponto. Pode ser algo tão simples quanto um erro de disco no host.
Matt
9

Você pode tentar algumas coisas,

  1. Você tem configuração de índices?

A indexação torna possível encontrar rapidamente registros sem fazer uma varredura completa da tabela primeiro, reduzindo drasticamente os tempos de execução.

CREATE INDEX idx_name ON addresses(name);
  1. Antes de executar a consulta, use a palavra-chave EXPLAIN primeiro,

Quando usado na frente de uma consulta SELECT, descreverá como o MySQL pretende executar a consulta e o número de linhas que ele precisará processar antes de terminar.

  1. Faça algumas alterações no mysql.ini, se for uma VM, aumente a RAM e configure o mysql.ini para ver se o desempenho aumenta.

Existem muitos otimizadores do MySQL por aí que podem guiá-lo.

Ajude isso ajuda

Anthony Fornito
fonte
Tudo bem, mas criar um índice em uma tabela muito pequena (<800 linhas) parece não ser tão útil quanto eu precisaria. Demora mais de um minuto para concluir a consulta citada acima. Uma verificação completa de uma tabela tão pequena não deve demorar tanto.
Tabb
Então ... você adicionou os índices? Se você não tiver certeza de qual é o problema, eu começaria o básico e continuaria trabalhando. Adicionar índices somente aumentará o desempenho se for feito corretamente.
Anthony Fornito 10/11
Sim, adicionei um índice na coluna de nome. Mas minha consulta acima nem tem cláusula WHERE restritiva, portanto, ela terá que ler a tabela inteira e imprimi-la. O índice adicionado não ajudou.
Tabb
Eu adicionei o resultado da consulta EXPLAIN acima. Parece bom para mim, mas o desempenho ainda é muito baixo. Não posso aumentar a RAM, pois não sou o administrador do gerenciador de virtualização. Mas htopmostra que apenas 307 MB de 2050 MB de RAM são usados.
Tabb
Sobre os índices, você realmente precisa pensar em quais colunas indexar, não deseja indexar tudo, indexar as que têm a maior quantidade, estou fazendo algumas suposições sobre isso, mas começaria com name'firstname'. Segundo, você tem certeza de que fez a indexação corretamente? possible_keys: NULL se a coluna for NULL, indica que nenhum índice relevante foi encontrado.
Anthony Fornito 10/11