У меня есть простая таблица с миллионами записей (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.
источник
SELECT
возвращает?1591 rows in set (16.48 sec)
Я снова выполнил запрос, поэтому продолжительность отличается. Это заняло сейчас 16 секунд (!!)Ответы:
Для тех, кто сталкивается с этим вопросом и задается вопросом, даже без обновления оперативной памяти, почему отправка данных занимает гораздо больше времени. Это потому, что отправка данных на самом деле включает время поиска данных, которые должны быть отправлены.
https://dev.mysql.com/doc/refman/5.7/en/general-thread-states.html
источник
Попробуйте Оптимизировать таблицу с помощью Оптимизировать имя таблицы и проверьте статус.
Большие изменения должны быть сделаны:
Это вам очень поможет, и, возможно, в таблице должен быть один первичный ключ, но вы добавили три столбца в качестве первичного ключа.
источник
Создайте отдельный индекс для id:
Чтобы этот индекс вступил в силу, перезапустите MySQL или
Если возможно, вы также можете изменить базу данных на InnoDB для поддержки транзакций и других преимуществ.
источник