非常慢的 MySQL 读取性能

Posted

技术标签:

【中文标题】非常慢的 MySQL 读取性能【英文标题】:Very Slow MySQL Read Performance 【发布时间】:2015-06-04 15:43:29 【问题描述】:

我在 mysql 中有下表:

CREATE TABLE tweetdb(
       tweetid BIGINT(18) UNSIGNED NOT NULL, 
       userid INT(10) UNSIGNED NOT NULL, 
       timestamp CHAR(14), 
       tweet TEXT, 
       score TINYINT, 
  PRIMARY KEY(tweetid, userid)
) ENGINE=MYISAM PARTITION BY KEY(userid) PARTITIONS 101;

+-----------+---------------------+------+-----+---------+-------+
| Field     | Type                | Null | Key | Default | Extra |
+-----------+---------------------+------+-----+---------+-------+
| tweetid   | bigint(18) unsigned | NO   | PRI | NULL    |       |
| userid    | int(10) unsigned    | NO   | PRI | NULL    |       |
| timestamp | char(14)            | YES  |     | NULL    |       |
| tweet     | text                | YES  |     | NULL    |       |
| score     | tinyint(4)          | YES  |     | NULL    |       |
+-----------+---------------------+------+-----+---------+-------+
5 rows in set (0.29 sec)

我在这个表中有 2.1 亿行。 我的 Undertow 服务器(Java 应用程序)发送带有以下选择查询的 GET:

"SELECT test.tweetdb.tweetid, test.tweetdb.tweet, test.tweetdb.score FROM test.tweetdb WHERE test.tweetdb.userid = 287543000 AND test.tweetdb.timestamp = 20140420000829;"

我使用用户 ID 和时间戳来获取结果,因为它是我唯一可用于测试数据库的数据。该数据库用于只读目的,没有写入/更新。

我还在桌子上使用了索引。

mysql> SHOW INDEX FROM tweetdb;
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table   | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| tweetdb |          1 | id_index |            1 | userid      | A         |           1 |     NULL | NULL   | YES  | BTREE      |         |               |
| tweetdb |          1 | id_index |            2 | timestamp   | A         |           1 |     NULL | NULL   | YES  | BTREE      |         |               |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
2 rows in set (0.00 sec)

现在,即使在使用分区和应用主键之后,也需要将近 1 秒才能得到正确的响应,这非常长。我的应用程序的吞吐量必须至少为每秒 6000 个请求。

硬件配置:

我正在运行 Undertow 服务器(前端)来查询 Amazon M1.large 实例上的 Mysql 服务器(后端)。为了避免延迟,我在同一个实例上运行两台服务器。

谁能帮帮我?我的想法不多了。 谢谢!

更新

mysql> EXPLAIN SELECT * FROM test.tweetdb LIMIT 1;
+----+-------------+---------+------+---------------+------+---------+------+-----------+-------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows      | Extra |
+----+-------------+---------+------+---------------+------+---------+------+-----------+-------+
|  1 | SIMPLE      | tweetdb | ALL  | NULL          | NULL | NULL    | NULL | 270119913 |       |
+----+-------------+---------+------+---------------+------+---------+------+-----------+-------+
1 row in set (3.67 sec)


mysql> EXPLAIN SELECT * FROM test.tweetdb WHERE test.tweetdb.userid=287543000 AND test.tweetdb.timestamp=20140420000829;
+----+-------------+---------+------+---------------+------+---------+------+---------+-------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows    | Extra       |
+----+-------------+---------+------+---------------+------+---------+------+---------+-------------+
|  1 | SIMPLE      | tweetdb | ALL  | NULL          | NULL | NULL    | NULL | 2657601 | Using where |
+----+-------------+---------+------+---------------+------+---------+------+---------+-------------+
1 row in set (0.00 sec)

Undertow 前端服务器的时间

【问题讨论】:

explain select ... 说什么? 更新了问题。 很清楚它没有使用任何索引,您可能需要将索引添加为alter table test.tweetdb add index user_timestamp_idx (userid,timestamp) 我已经有一个参数相同的索引了。 嗯,我错过了这个问题。 【参考方案1】:

您的主键是 tweetid 和 userid 的组合。而对于 mysql,它将进行完整搜索,因为您的表具有组合列的主键。您可以创建另一个只有用户 ID 的密钥。 对于 mysql,如果您在 key 中有两列,那么它们应该出现在其中,否则它会考虑将其用于整个表搜索

【讨论】:

在我的数据集中,用户 ID 和时间戳组合不是唯一的。一个 twitterbot 可以同时创建多条推文。我想在 tweetid、userid 和时间戳上创建一个主键,但是将数据加载到表中需要很长时间。您是否建议我将主键全部删除?

以上是关于非常慢的 MySQL 读取性能的主要内容,如果未能解决你的问题,请参考以下文章

sql server接收信息速度慢的原因

JCIFS读取远程服务器文件过慢的解决方法

MySQL中like查询速度慢的问题

mysql 三星索引设置

160304mysql数据库插入速度和读取速度的调整记录

简单快速的读取过程