MySQL слишком долго, чтобы отправить данные


9

У меня есть простая таблица с миллионами записей (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возвращает?
hjpotter92

1591 rows in set (16.48 sec)Я снова выполнил запрос, поэтому продолжительность отличается. Это заняло сейчас 16 секунд (!!)
rlcabral

вместо использования * попробуйте использовать столбцы, а затем посмотрите, какая разница
Мухаммед Рахил

Нет. Тот же результат.
rlcabral

Попробуйте сделать столбец идентификаторов простым первичным индексом. Поскольку ID должен быть уникальным полем, вам не нужно создавать сложные индексы с ним. Это должно сделать поиск по первичному ключу быстрым, как скорость света.
Александр Правдин

Ответы:


1

Для тех, кто сталкивается с этим вопросом и задается вопросом, даже без обновления оперативной памяти, почему отправка данных занимает гораздо больше времени. Это потому, что отправка данных на самом деле включает время поиска данных, которые должны быть отправлены.

https://dev.mysql.com/doc/refman/5.7/en/general-thread-states.html

Поток читает и обрабатывает строки для оператора SELECT и отправляет данные клиенту. Поскольку операции, происходящие во время этого состояния, имеют тенденцию выполнять большие объемы доступа к диску (чтения), это часто является самым длительным состоянием в течение времени жизни данного запроса.


-2

Попробуйте Оптимизировать таблицу с помощью Оптимизировать имя таблицы и проверьте статус.

Большие изменения должны быть сделаны:

Alter table tablename engine = 'INNODB'

Это вам очень поможет, и, возможно, в таблице должен быть один первичный ключ, но вы добавили три столбца в качестве первичного ключа.


-3

Создайте отдельный индекс для id:

изменить детали таблицы добавить ключ d1 (id);

Чтобы этот индекс вступил в силу, перезапустите MySQL или

анализировать детали таблицы;

Если возможно, вы также можете изменить базу данных на InnoDB для поддержки транзакций и других преимуществ.


Как это поможет?
Colin 't Hart
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.