У мене проста таблиця з мільйонами записів (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 полів (рядок середнього рівня 59 байт) і не має фантазійних функцій. Будь-яка ідея, що може бути причиною цього?
Примітка: id - ідентифікатор користувача. Кожен користувач може мати принаймні один запис на кожну годину кожного дня. Тому ідентифікатор не є унікальним.
Редагувати: У мене є ще одна таблиця з такою ж структурою і набагато більше рядків (34 мільйони). Якщо я запускаю той самий запит у цій великій таблиці, він повертає результати менше ніж за 1 секунду.
Єдина відмінність полягає в тому, що більша таблиця не отримує стільки запитів, скільки менша.
- Чи можливо кількість запитів уповільнює процес? Кеш MySQL увімкнено. Я також кешував кешування запитів, щоб зменшити кількість запитів.
- Можливо, файл, де збережена таблиця, пошкоджений чи щось?
Оновлення Проблему було вирішено шляхом відокремлення рівня даних від веб-рівня. Рівень даних також отримав оновлення оперативної пам’яті та працює на raid10.
1591 rows in set (16.48 sec)
Я знову запустив запит, тому тривалість різна. Зараз
SELECT
повертається?