mysql - 在 MySQL 中按日期时间范围选择非常慢

标签 mysql sql database performance myisam

我的表 posts 有超过 650 万条记录。每个帖子都使用固定长度的 name 表示。我使用 MySQL Community 5.7,具有大约 10K-20K IOPS 和 1GB 内存的 SSD 磁盘,key-buffer-size 设置为 512M(顺便说一句,大多数时候我使用默认的 MySQL 配置驱动)。我的资源有限,因此我选择了 MyISAM 作为我的存储引擎。我的基准测试表明,在我的情况下,MyISAM 更快。我也不太关心数据,因为它可以更新。

所以,这是我的方案信息:

+------------+--------+------------+
| TABLE_NAME | ENGINE | row_format |
+------------+--------+------------+
| posts      | MyISAM | Fixed      |
+------------+--------+------------+

+---------------------+---------------------+------+-----+---------+----------------+
| Field               | Type                | Null | Key | Default | Extra          |
+---------------------+---------------------+------+-----+---------+----------------+
| id                  | int(11) unsigned    | NO   | PRI | NULL    | auto_increment |
| name                | char(30)            | NO   | UNI | NULL    |                |
| worker_id           | tinyint(4) unsigned | NO   | MUL | NULL    |                |
| processing_priority | tinyint(4) unsigned | NO   | MUL | 0       |                |
| last_processed_at   | datetime            | YES  | MUL | NULL    |                |
| scraped_at          | datetime            | NO   | MUL | NULL    |                |
+---------------------+---------------------+------+-----+---------+----------------+

+-------+------------+---------------------+--------------+---------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name            | Seq_in_index | Column_name         | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+---------------------+--------------+---------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| posts |          0 | PRIMARY             |            1 | id                  | A         |     6579588 |     NULL | NULL   |      | BTREE      |         |               |
| posts |          0 | name                |            1 | name                | A         |     6579588 |     NULL | NULL   |      | BTREE      |         |               |
| posts |          1 | last_processed_at   |            1 | last_processed_at   | A         |     6579588 |     NULL | NULL   | YES  | BTREE      |         |               |
| posts |          1 | processing_priority |            1 | processing_priority | A         |           3 |     NULL | NULL   |      | BTREE      |         |               |
| posts |          1 | worker_id           |            1 | worker_id           | A         |          50 |     NULL | NULL   |      | BTREE      |         |               |
| posts |          1 | scraped_at          |            1 | scraped_at          | A         |      234985 |     NULL | NULL   |      | BTREE      |         |               |
+-------+------------+---------------------+--------------+---------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

我运行的查询:

SELECT COUNT(*) FROM `posts` WHERE `posts`.`worker_id` = 1 AND (last_processed_at >= '2017-11-04 22:20:27.203761')

MySQL 需要 3676.4ms 来执行这个查询。

查询解释:

+----+-------------+-------+------------+------+-----------------------------+-----------+---------+-------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys               | key       | key_len | ref   | rows   | filtered | Extra       |
+----+-------------+-------+------------+------+-----------------------------+-----------+---------+-------+--------+----------+-------------+
|  1 | SIMPLE      | posts | NULL       | ref  | last_processed_at,worker_id | worker_id | 1       | const | 232621 |    37.45 | Using where |
+----+-------------+-------+------------+------+-----------------------------+-----------+---------+-------+--------+----------+-------------+

您对如何优化它有任何想法吗?

最佳答案

您可以使用 worker_idlast_processed_at 创建组合键,替换 worker_id 键。

关于mysql - 在 MySQL 中按日期时间范围选择非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47120493/

相关文章:

Mysql - 我可以获取子选择结果并在 WHERE 子句中使用它吗?

database - 显示oracle数据库的所有 View

sql - 在 SSRS 查询中显示从日期开始的年月

MySQL MATCH() AGAINST() 与相反的参数

mysql - VBA将记录从一个表移动到另一个表

php - 摆脱重复的行

简单联合的情况下的SQL查询性能

mysql - 使用数据透视表的 Laravel Eloquent 多对多关系

java - 无法获取Java中特定索引中的对象

mysql - 检查 MySQL 架构更改的进度