Eu tenho uma tabela simples com milhões de registros (14.000.000) e, para uma consulta simples, está gastando muito tempo "enviando dados".
A mesa
CREATE TABLE IF NOT EXISTS details (
id int(11) NOT NULL,
date date NOT NULL,
time int(2) NOT NULL,
minutes_online decimal(5,0) NOT NULL,
minutes_playing decimal(5,0) NOT NULL,
minutes_chatting decimal(5,0) NOT NULL,
minutes_away decimal(5,0) NOT NULL
PRIMARY KEY (id,date,time)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
A consulta simples
mysql> SELECT * FROM details WHERE id = 3014595;
Explicar
mysql> EXPLAIN SELECT * FROM details WHERE id = 3014595;
+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------+
| 1 | SIMPLE | details | ref | PRIMARY | PRIMARY | 4 | const | 1482 | |
+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------+
Perfil para a consulta
mysql> SHOW PROFILE FOR QUERY 1;
+--------------------------------+----------+
| Status | Duration |
+--------------------------------+----------+
| starting | 0.000024 |
| checking query cache for query | 0.000078 |
| checking permissions | 0.000014 |
| Opening tables | 0.000126 |
| System lock | 0.000011 |
| Table lock | 0.000030 |
| init | 0.000027 |
| optimizing | 0.000117 |
| statistics | 0.040077 |
| preparing | 0.000029 |
| executing | 0.000006 |
| Sending data | 7.536960 |
| end | 0.000013 |
| query end | 0.000004 |
| freeing items | 0.000037 |
| storing result in query cache | 0.000006 |
| logging slow query | 0.000003 |
| cleaning up | 0.000006 |
+--------------------------------+----------+
Como você pode ver, o SELECT
instrução usou o índice e leu apenas 1482 linhas. No entanto, a consulta passou 7.536960 segundos enviando os dados. É como se a consulta lesse muito mais linhas necessárias.
É uma consulta simples, com apenas 7 campos (linha média de 59 bytes) e nenhuma função sofisticada. Alguma idéia do que pode estar causando isso?
Nota: id é o ID do usuário. Cada usuário pode ter pelo menos uma entrada para cada hora do dia. Portanto, id não é exclusivo.
Edit: Eu tenho outra tabela com a mesma estrutura e muito mais linhas (34 milhões). Se eu executar a mesma consulta nessa tabela maior, ele retornará os resultados em menos de 1 segundo.
A única diferença é que a tabela maior não recebe tantas consultas quanto a tabela menor.
- É possível que o número de consultas esteja atrasando o processo? O cache do MySQL está ativado. Também tenho o CakePHP armazenando em cache as consultas para reduzir o número de consultas.
- É possível que o arquivo em que a tabela está salva esteja corrompido ou algo assim?
Atualização O problema foi resolvido separando a camada de dados da camada da web. A camada de dados também recebeu uma atualização na RAM e está sendo executada no raid10.
fonte
SELECT
retorno?1591 rows in set (16.48 sec)
Eu executei a consulta novamente, é por isso que a duração é diferente. Demorou agora 16 segundos (!!)Respostas:
Para quem se depara com essa pergunta e se pergunta, mesmo sem a atualização da RAM, por que o envio de dados estava demorando muito mais. Isso ocorre porque o envio de dados realmente inclui o tempo de pesquisa nos dados que devem ser enviados.
https://dev.mysql.com/doc/refman/5.7/en/general-thread-states.html
fonte
Tente otimizar a tabela usando o nome da tabela Otimizar tabela e verifique o status.
Grandes mudanças precisam ser feitas:
Isso o ajudará muito e, possivelmente, deve haver uma chave primária na tabela, mas você adicionou três colunas como chave primária.
fonte
Crie um índice separado para o ID:
Para colocar esse índice em vigor, reinicie o MySQL ou
Se possível, você também pode alterar o banco de dados para o InnoDB para suporte à transação e outros benefícios.
fonte