[深入理解MySQL系列] - sort_buffer

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介:
注:本系列文章主要探讨  MySQL 内存利用以及执行计划相关的一些知识点,从而为  MySQL 优化打下更好的基础。

环境说明

OS: AS4U6, 2.6.9-67.0.15.ELsmp, 16G Ram, MD3000阵列, xfs文件系统
MySQL 5.1.26 - percona(innodb plugin, innodb stat, user stat, msl, show patch, acc-pslist 补丁)
MySQL 主要配置参数
default_table_type = innodb
log_slow_queries
long_query_time = 0.001
log_slow_verbosity=query_plan,innodb
innodb_data_file_path = ibdata1:1024M:autoextend
innodb_log_file_size = 400M
innodb_log_files_in_group = 3
innodb_file_per_table
innodb_file_format="Barracuda"
其他参数均为默认值,因此其他几个内存相关参数值如下:
innodb_buffer_pool_size = 8388608
join_buffer_size = 131072
key_buffer_size = 8388600
max_heap_table_size = 16777216
query_cache_size = 0
read_buffer_size = 131072
read_rnd_buffer_size = 262144
sort_buffer_size = 2097144
tmp_table_size = 16777216
以后的所有例子中,如果没有特地注明,则测试相关的表都使用  InnoDB 引擎。

1、 排序缓冲

相关参数: sort_buffer_size, read_rnd_buffer_size

1.1 利用InnoDB的主键进行排序

EXPLAIN SELECT SQL_NO_CACHE * FROM T1 WHERE ID<10000 ORDER BY ID DESC;
+----+-------------+-------+-------+---------------+---------+---------+------+-------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows  | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+-------+-------------+
|  1 | SIMPLE      | T1    | range | PRIMARY       | PRIMARY | 8       | NULL | 14872 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+------+-------+-------------+
# Query_time: 0.207893  Lock_time: 0.000056  Rows_sent: 9999  Rows_examined: 9999
# QC_Hit: No  Full_scan: No  Full_join: No  Tmp_table: No  Tmp_table_on_disk: No
# Filesort: No  Filesort_on_disk: No  Merge_passes: 0
#   InnoDB_IO_r_ops: 91  InnoDB_IO_r_bytes: 1490944  InnoDB_IO_r_wait: 0.083391
#   InnoDB_rec_lock_wait: 0.000000  InnoDB_queue_wait: 0.000000
#   InnoDB_pages_distinct: 93
SELECT SQL_NO_CACHE * FROM T1 WHERE ID<10000 ORDER BY ID DESC;
由于是针对主键/索引进行排序,因此无需使用临时表

1.2 利用 InnoDB 使用非索引字段排序

EXPLAIN SELECT SQL_NO_CACHE * FROM T1 WHERE ID<10000 ORDER BY C1 DESC;
+----+-------------+-------+-------+---------------+---------+---------+------+-------+-----------------------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows  | Extra                       |
+----+-------------+-------+-------+---------------+---------+---------+------+-------+-----------------------------+
|  1 | SIMPLE      | T1    | range | PRIMARY       | PRIMARY | 8       | NULL | 14872 | Using where; Using filesort |
+----+-------------+-------+-------+---------------+---------+---------+------+-------+-----------------------------+
# Query_time: 0.120879  Lock_time: 0.000023  Rows_sent: 9999  Rows_examined: 19998
# QC_Hit: No  Full_scan: No  Full_join: No  Tmp_table: No  Tmp_table_on_disk: No
# Filesort: Yes  Filesort_on_disk: Yes  Merge_passes: 1
#   InnoDB_IO_r_ops: 0  InnoDB_IO_r_bytes: 0  InnoDB_IO_r_wait: 0.000000
#   InnoDB_rec_lock_wait: 0.000000  InnoDB_queue_wait: 0.000000
#   InnoDB_pages_distinct: 93
SELECT SQL_NO_CACHE * FROM T1 WHERE ID<10000 ORDER BY C1 DESC;
由于  C1 不是索引字段,因此需要额外排序,并且由于  sort_buffer 和  read_rnd_buffer 不够大,也用到了磁盘文件。
加大  sort_buffer_size,再看看
set session sort_buffer_size = 1024 * 1024 * 5;
再次执行刚才的测试,结果发生了变化。
# Query_time: 0.080727  Lock_time: 0.000030  Rows_sent: 9999  Rows_examined: 19998
# QC_Hit: No  Full_scan: No  Full_join: No  Tmp_table: No  Tmp_table_on_disk: No
# Filesort: Yes  Filesort_on_disk: No  Merge_passes: 0
#   InnoDB_IO_r_ops: 0  InnoDB_IO_r_bytes: 0  InnoDB_IO_r_wait: 0.000000
#   InnoDB_rec_lock_wait: 0.000000  InnoDB_queue_wait: 0.000000
#   InnoDB_pages_distinct: 93
SELECT SQL_NO_CACHE * FROM T1 WHERE ID<10000 ORDER BY C1 DESC;
可以看到, Filesort_on_disk 变成了  NoMerge_passes 也变成了  0,表示无需使用磁盘文件,而直接在内存里排序。

1.3 加大 read_rnd_buffer_size 看看对 filesort 是否有影响

EXPLAIN SELECT SQL_NO_CACHE * FROM T1 AS T1 WHERE ID<10000 ORDER BY C1 DESC;
+----+-------------+-------+-------+---------------+---------+---------+------+-------+-----------------------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows  | Extra                       |
+----+-------------+-------+-------+---------------+---------+---------+------+-------+-----------------------------+
|  1 | SIMPLE      | T1    | range | PRIMARY       | PRIMARY | 8       | NULL | 14872 | Using where; Using filesort |
+----+-------------+-------+-------+---------------+---------+---------+------+-------+-----------------------------+
# Query_time: 0.103654  Lock_time: 0.000045  Rows_sent: 9999  Rows_examined: 19998
# QC_Hit: No  Full_scan: No  Full_join: No  Tmp_table: No  Tmp_table_on_disk: No
# Filesort: Yes  Filesort_on_disk: Yes  Merge_passes: 1
#   InnoDB_IO_r_ops: 0  InnoDB_IO_r_bytes: 0  InnoDB_IO_r_wait: 0.000000
#   InnoDB_rec_lock_wait: 0.000000  InnoDB_queue_wait: 0.000000
#   InnoDB_pages_distinct: 93
SELECT SQL_NO_CACHE * FROM T1 AS T1 WHERE ID<10000 ORDER BY C1 DESC;
具体过程不再每次重复贴了,结果是从  1M 到  512M,发现一直没什么变化,对 filesort 没什么帮助。 待续......

本文转自叶金荣51CTO博客,原文链接:http://blog.51cto.com/imysql/308839,如需转载请自行联系原作者
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
6月前
|
关系型数据库 MySQL 数据库
MySQL 的 change buffer 是什么?
MySQL 的 change buffer 是什么?
|
SQL 算法 关系型数据库
MySQL参数优化之join_buffer_size
MySQL参数优化之join_buffer_size
503 0
MySQL参数优化之join_buffer_size
|
存储 关系型数据库 MySQL
【MySQL】sort_buffer_size=128M,是干什么的?底层原理是什么?
【MySQL】sort_buffer_size=128M,是干什么的?底层原理是什么?
463 0
|
存储 关系型数据库 MySQL
【MySQL】myisam_max_sort_file_size=64G,是干什么的?底层原理是什么?
【MySQL】myisam_max_sort_file_size=64G,是干什么的?底层原理是什么?
664 0
|
缓存 关系型数据库 MySQL
【MySQL】read_rnd_buffer_size=4M,是干什么的?底层原理是什么?
【MySQL】read_rnd_buffer_size=4M,是干什么的?底层原理是什么?
889 0
|
SQL 缓存 监控
一文带你了解MySQL之Change Buffer
上一篇文章一文带你了解MySQL数据库InnoDB_Buffer_Pool(点击跳转)我们学习了InnoDB Buffer Pool的工作原理,其作用是减少MySQL读取数据时直接与磁盘打交道的次数。那么写入数据时MySQL是否做了减少IO的优化呢?答案是肯定的,就要我们深入的学习Change Buffer。
499 0
一文带你了解MySQL之Change Buffer
|
存储 SQL 关系型数据库
一文带你了解MySQL之Log Buffer
上一篇文章我们首次提到Redo Log的概念,Redo Log是数据库体系架构中非常重要的一个模块,它能保证数据库的Crash-safe(崩溃恢复)的能力。而今天要介绍的Log Buffer正和Redo Log息息相关、密不可分。所以我们就来一起来了解它。
646 0
|
存储 缓存 关系型数据库
【MySQL】myisam_sort_buffer_size=32M,是干什么的?底层原理是什么?
【MySQL】myisam_sort_buffer_size=32M,是干什么的?底层原理是什么?
462 0
|
缓存 关系型数据库 MySQL
【MySQL】sort_buffer_size=256kb,是干什么的?底层原理是什么?
【MySQL】sort_buffer_size=256kb,是干什么的?底层原理是什么?
522 0
|
算法 关系型数据库 MySQL
【MySQL】join_buffer_size=2M,是干什么的?底层原理是什么?
【MySQL】join_buffer_size=2M,是干什么的?底层原理是什么?
214 0