У меня есть простая таблица с миллионами записей (14 000 000), и для простого запроса она тратит слишком много времени на «отправку данных».
Стол
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;
Простой запрос
mysql> SELECT * FROM details WHERE id = 3014595;
объяснять
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 | |
+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------+
Профиль для запроса
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 |
+--------------------------------+----------+
Как видите, SELECT
оператор использовал индекс и прочитал только 1482 строки. Тем не менее, запрос потратил 7,536960 секунд на отправку данных. Это похоже на то, что запрос прочитал гораздо больше нужных ему строк.
Это простой запрос, всего 7 полей (строка avg 59 байт) и не требующая особой функции. Есть идеи, что может быть причиной этого?
Примечание: id - это идентификатор пользователя. Каждый пользователь может иметь как минимум одну запись на каждый час каждого дня. Следовательно, id не уникален.
Изменить: у меня есть еще одна таблица с той же структурой и гораздо больше строк (34 миллиона). Если я выполню тот же запрос для этой таблицы большего размера, он вернет результаты менее чем за 1 секунду.
Единственное отличие состоит в том, что большая таблица не получает столько запросов, сколько меньшая таблица.
- Возможно ли, что количество запросов замедляет процесс? Кеш MySQL включен. Я также CakePHP кэширует запросы, чтобы уменьшить количество запросов.
- Возможно ли, что файл, в котором сохранена таблица, поврежден или что-то в этом роде?
Обновление Проблема была решена путем отделения уровня данных от веб-уровня. Уровень данных также получил обновление оперативной памяти и работает на raid10.
1591 rows in set (16.48 sec)
Я снова выполнил запрос, поэтому продолжительность отличается. Это заняло сейчас 16 секунд (!!)
SELECT
возвращает?