mysql demorando muito para enviar dados

9

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.

rlcabral
fonte
Quantas linhas o SELECTretorno?
Hjpotter92
1591 rows in set (16.48 sec)Eu executei a consulta novamente, é por isso que a duração é diferente. Demorou agora 16 segundos (!!)
rlcabral
em vez de usar * tentar usar colunas e depois ver que diferença faz
Muhammad Raheel
Não. Mesmo resultado.
Rlcabral
Tente fazer da coluna ID um índice primário simples. Como o ID deve ser um campo exclusivo, você não precisa criar índices complexos com ele. Isso deve acelerar sua pesquisa por chave primária como uma velocidade da luz.
Alexander Pravdin

Respostas:

1

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

O encadeamento está lendo e processando linhas para uma instrução SELECT e enviando dados para o cliente. Como as operações que ocorrem durante esse estado tendem a executar grandes quantidades de acesso ao disco (leituras), geralmente é o estado de execução mais longa durante a vida útil de uma determinada consulta.

vaibhav gupta
fonte
-2

Tente otimizar a tabela usando o nome da tabela Otimizar tabela e verifique o status.

Grandes mudanças precisam ser feitas:

Alter table tablename engine = 'INNODB'

Isso o ajudará muito e, possivelmente, deve haver uma chave primária na tabela, mas você adicionou três colunas como chave primária.

SAM AB
fonte
-3

Crie um índice separado para o ID:

alterar os detalhes da tabela, adicionar a chave d1 (id);

Para colocar esse índice em vigor, reinicie o MySQL ou

analisar detalhes da tabela;

Se possível, você também pode alterar o banco de dados para o InnoDB para suporte à transação e outros benefícios.

Krishnakumar
fonte
Como isso vai ajudar?
Colin 't Hart