Tengo una tabla simple con millones de registros (14,000,000) y para una consulta simple está pasando demasiado tiempo "enviando datos".
La 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;
La consulta simple
mysql> SELECT * FROM details WHERE id = 3014595;
Explique
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 la 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 puede ver, la SELECT
declaración usó el índice y solo leyó 1482 filas. Sin embargo, la consulta pasó 7.536960 segundos enviando los datos. Es como si la consulta leyera muchas más filas que necesitaba.
Es una consulta simple, con solo 7 campos (promedio de fila de 59 Bytes) y sin función sofisticada. ¿Alguna idea de lo que puede estar causando esto?
Nota: id es la identificación del usuario. Cada usuario puede tener al menos una entrada por cada hora de cada día. Por lo tanto, la identificación no es única.
Editar: Tengo otra tabla con la misma estructura y muchas más filas (34 millones). Si ejecuto la misma consulta en esta tabla más grande, devuelve los resultados en menos de 1 segundo.
La única diferencia es que la tabla más grande no recibe tantas consultas como la tabla más pequeña.
- ¿Es posible que el número de consultas esté ralentizando el proceso? El caché de MySQL está activado. También he almacenado en caché CakePHP las consultas para reducir el número de consultas.
- ¿Es posible que el archivo donde se guarda la tabla esté dañado o algo así?
Actualización El problema se resolvió separando el nivel de datos del nivel web. El nivel de datos también obtuvo una actualización en la RAM y se está ejecutando en raid10.
fuente
SELECT
devuelve?1591 rows in set (16.48 sec)
Volví a ejecutar la consulta, por eso la duración es diferente. Tomó ahora 16 segundos (!!)Respuestas:
Para cualquiera que tropiece con esta pregunta y se pregunte, incluso sin la actualización de RAM, por qué enviar datos tardaba tanto. Esto se debe a que el envío de datos en realidad incluye el tiempo de búsqueda de los datos que se enviarán.
https://dev.mysql.com/doc/refman/5.7/en/general-thread-states.html
fuente
Intente Optimizar la tabla usando Optimizar tabla nombre de tabla y verifique el estado.
Grandes cambios deben hacerse:
Esto lo ayudará mucho y posiblemente debería haber una clave principal en la tabla, pero ha agregado tres columnas como clave principal.
fuente
Crear índice separado para id:
Para que este índice surta efecto, reinicie MySQL o
Si es posible, también puede cambiar la base de datos a InnoDB para soporte de transacciones y otros beneficios.
fuente