大型表中排序查询的 mysql 性能改进

标签 mysql sql

表结构:

CREATE TABLE `mytable` (
  `id` varchar(8) NOT NULL,
  `event` varchar(32) NOT NULL,
  `event_date` date NOT NULL,
  `event_time` time NOT NULL,
  KEY `id` (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8

此表中的数据如下所示:

 id      | event      | event_date  | event_time
---------+------------+-------------+-------------
ref1     | someevent1 | 2010-01-01  | 01:23:45
ref1     | someevent2 | 2010-01-01  | 02:34:54
ref1     | someevent3 | 2010-01-18  | 01:23:45
ref2     | someevent4 | 2012-10-05  | 22:23:21
ref2     | someevent5 | 2012-11-21  | 11:22:33

该表包含大约 500.000.000 条与此类似的记录。

我想在这里询问的查询如下所示:

SELECT     *
FROM       `mytable`
WHERE      `id` = 'ref1'
ORDER BY   event_date DESC,
           event_time DESC
LIMIT      0, 500

EXPLAIN 输出如下:

select_type:   SIMPLE
table:         E
type:          ref
possible_keys: id
key:           id
key_len:       27
ref:           const     
rows:          17024 (a common example)
Extra:         Using where; Using filesort

目的: 此查询由网站生成,LIMIT 值用于页面导航元素,因此如果用户想要查看较旧的条目,它们将调整为 500、500,然后是 1000、500 等等。

由于id字段中的一些项可以设置在相当多的行中,行数越来越多当然会导致查询变慢。分析那些缓慢的查询向我展示了排序的原因,在查询期间的大部分时间 mysql 服务器忙于对数据进行排序。索引字段 event_dateevent_time 并没有太大改变。

示例 SHOW PROFILE 结果,按持续时间排序:

state          | duration/sec | percentage
---------------|--------------|-----------
Sorting result |     12.00145 |   99.80640
Sending data   |      0.01978 |    0.16449
statistics     |      0.00289 |    0.02403
freeing items  |      0.00028 |    0.00233
...
Total          |     12.02473 |  100.00000

现在问题:

在深入研究像 sort_buffer_size 这样的 mysql 变量之前和其他服务器配置选项,您能否想出任何方法来更改查询或排序行为,以便排序不再是一个大的性能消耗者并且此查询的目的仍然存在?

我不介意有一点跳出框框的想法。

提前致谢!

最佳答案

正如我在评论中所写,多列索引(id、evet_date desc、event_time desc)可能会有所帮助。

如果此表增长很快,您应该考虑在应用程序中添加选项,供用户选择特定日期范围内的数据。

示例:第一步始终返回 500 条记录,但要选择下一条记录,用户应设置数据的日期范围,然后设置分页。

关于大型表中排序查询的 mysql 性能改进,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13308799/

相关文章:

mysql - 陷入在 MySQL 中创建简单过程的困境 [IF 语句]

sql - 了解 "Where"子句中的 case 表达式

mysql - 更改 MySQL 磁盘上的数据组织

php - Mysql多选排除行

MySQL更新 'categories'链接表

mysql - SHA1 和作为主键?

python - 嵌套集模型和 SQLAlchemy——添加新节点

MySQL 连接返回从另一个表链接的不同 ID

php - 从 postgresql 后端的存储过程中检索通知

sql - 使用sql基于时间的过滤