У меня есть таблица с примерно 120k строк, которая содержит поле с BLOB (не более 1 МБ каждая запись в размере, как правило, гораздо меньше). Моя проблема в том, что всякий раз, когда я запускаю запрос, запрашивающий какие-либо столбцы в этой таблице (не включая BLOB), если кэш файловой системы пуст, для его завершения требуется приблизительно 40 ''. Для всех последующих запросов к одной и той же таблице требуется меньше 1 '' (тестирование из клиента командной строки, на самом сервере). Количество строк, возвращаемых в запросах, варьируется от пустого набора до 60k+
Я удалил кеш запросов, чтобы он не имел к этому никакого отношения. Таблица myisam, но я также попытался изменить ее на innodb (и установив ROW_FORMAT = COMPACT), но безуспешно.
Если я удаляю столбец BLOB, запрос всегда выполняется быстро.
Поэтому я бы предположил, что сервер читает двоичные объекты с диска (или их частей), а файловая система их кэширует. Проблема в том, что на сервере с большим трафиком и ограниченной памятью кэш файловой системы обновляется время от времени, поэтому этот конкретный запрос продолжает вызывать у меня проблемы.
Итак, мой вопрос, есть ли способ значительно ускорить процесс, не удаляя столбец blob из таблицы?
Вот 2 примера запросов, выполняемых один за другим, а также объяснение, индексы и определение таблицы:
mysql> SELECT ct.score FROM completed_tests ct where ct.status != 'deleted' and ct.status != 'failed' and score < 100;
Empty set (48.21 sec)
mysql> SELECT ct.score FROM completed_tests ct where ct.status != 'deleted' and ct.status != 'failed' and score < 99;
Empty set (1.16 sec)
mysql> explain SELECT ct.score FROM completed_tests ct where ct.status != 'deleted' and ct.status != 'failed' and score < 99;
+----+-------------+-------+-------+---------------+--------+---------+------+-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+--------+---------+------+-------+-------------+
| 1 | SIMPLE | ct | range | status,score | status | 768 | NULL | 82096 | Using where |
+----+-------------+-------+-------+---------------+--------+---------+------+-------+-------------+
1 row in set (0.00 sec)
mysql> show indexes from completed_tests;
+-----------------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-----------------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| completed_tests | 0 | PRIMARY | 1 | id | A | 583938 | NULL | NULL | | BTREE | |
| completed_tests | 1 | users_login | 1 | users_LOGIN | A | 11449 | NULL | NULL | YES | BTREE | |
| completed_tests | 1 | tests_ID | 1 | tests_ID | A | 140 | NULL | NULL | | BTREE | |
| completed_tests | 1 | status | 1 | status | A | 3 | NULL | NULL | YES | BTREE | |
| completed_tests | 1 | timestamp | 1 | timestamp | A | 291969 | NULL | NULL | | BTREE | |
| completed_tests | 1 | archive | 1 | archive | A | 1 | NULL | NULL | | BTREE | |
| completed_tests | 1 | score | 1 | score | A | 783 | NULL | NULL | YES | BTREE | |
| completed_tests | 1 | pending | 1 | pending | A | 1 | NULL | NULL | | BTREE | |
+-----------------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
mysql> show create table completed_tests;
+-----------------+--------------------------------------
| Table | Create Table |
+-----------------+--------------------------------------
| completed_tests | CREATE TABLE 'completed_tests' (
'id' mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
'users_LOGIN' varchar(100) DEFAULT NULL,
'tests_ID' mediumint(8) unsigned NOT NULL DEFAULT '0',
'test' longblob,
'status' varchar(255) DEFAULT NULL,
'timestamp' int(10) unsigned NOT NULL DEFAULT '0',
'archive' tinyint(1) NOT NULL DEFAULT '0',
'time_start' int(10) unsigned DEFAULT NULL,
'time_end' int(10) unsigned DEFAULT NULL,
'time_spent' int(10) unsigned DEFAULT NULL,
'score' float DEFAULT NULL,
'pending' tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY ('id'),
KEY 'users_login' ('users_LOGIN'),
KEY 'tests_ID' ('tests_ID'),
KEY 'status' ('status'),
KEY 'timestamp' ('timestamp'),
KEY 'archive' ('archive'),
KEY 'score' ('score'),
KEY 'pending' ('pending')
) ENGINE=InnoDB AUTO_INCREMENT=117996 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED
1 row in set (0.00 sec)
Я первоначально разместил это в запросе MySQL медленно сначала быстро, а потом, но теперь у меня есть больше информации, поэтому я делаю репост как другой вопрос Я также разместил это на форуме mysql, но не получил ответа
Заранее спасибо как всегда