包含blob的表上的mysql查询速度取决于文件系统缓存 [英] Speed of mysql query on tables containing blob depends on filesystem cache

查看:102
本文介绍了包含blob的表上的mysql查询速度取决于文件系统缓存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个约有12万行的表,其中包含一个带BLOB的字段(每个条目的大小不超过1MB,通常小得多).我的问题是,每当我运行查询询问此表上的任何列(,包括BLOB在内)时,如果文件系统缓存为空,则大约需要40英寸才能完成.同一张表上的所有后续查询都需要少于1英寸的内容(从服务器本身的命令行客户端进行测试).查询中返回的行数从空集到60k +

I have a table with approximately 120k rows, which contains a field with a BLOB (not more than 1MB each entry in size, usually much less). My problem is that whenever I run a query asking any columns on this table (not including the BLOB one), if the filesystem cache is empty, it takes approximately 40'' to complete. All subsequent queries on the same table require less than 1'' (testing from the command line client, on the server itself). The number of rows returned in the queries vary from an empty set to 60k+

我已经消除了查询缓存,因此与它无关. 该表是myisam,但我也尝试将其更改为innodb(并设置ROW_FORMAT = COMPACT),但是没有任何运气.

I have eliminated the query cache so it has nothing to do with it. The table is myisam but I also tried to change it to innodb (and setting ROW_FORMAT=COMPACT), but without any luck.

如果删除BLOB列,则查询总是很快.

If I remove the BLOB column, the query is always fast.

因此,我假设服务器从磁盘(或其一部分)读取blob,然后文件系统对其进行缓存.问题是在具有高流量和有限内存的服务器上,文件系统缓存偶尔会刷新一次,因此此特定查询不断给我带来麻烦.

So I would assume that the server reads the blobs from the disk (or parts of them) and the filesystem caches them. The problem is that on a server with high traffic and limited memory, the filesystem cache is refreshed every once in a while, so this particular query keeps causing me trouble.

所以我的问题是,有没有一种方法可以在不从表中删除blob列的情况下大大加快速度?

So my question is, is there a way to considerably speed things up, without removing the blob column from the table?

这里有2个示例查询,一个接一个地运行,以及解释,索引和表定义:

here are 2 example queries, ran one after the other, along with explain, indexes and table definition:

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论坛上,但我还没回来

I originally posted this on mysql query slow at first fast afterwards but I now have more information so I repost as a different question I also posted this on the mysql forum, but I haven't heard back

一如既往地感谢

推荐答案

我对此问题进行了一段时间的研究.许多人建议在单独的表中仅使用具有一个主键的blob,并使用具有blob表外键的blob将元数据存储在另一表中.这样,性能将大大提高.

I was doing research on this issue for a while. Many people recommend using blob with only one primary key in a separate table and storing the blobs meta data in another table with a foreign key to the blob table. With this the performance will be higher considerably.

这篇关于包含blob的表上的mysql查询速度取决于文件系统缓存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆