系列文档参考 MYSQL系列-整体架构介绍
排序缓冲区(Sort Buffer)
MYSQL排序整体过程
- server 层从存储引擎读取符合 where 条件的记录,写入一个专门存放待排序记录的内存区域,这个内存区域叫做
排序缓冲区(sort buffer)
。 - 排序缓冲区写满之后,会对缓冲区中的记录进行排序,排好序的记录组成一个
数据块
,数据块包含Merge_chunk
和数据记录
两部分,Merge_chunk 写入一个磁盘文件(chunk_file),数据记录写入另一个磁盘文件(temp_file)。Merge_chunk 中保存着数据记录
在磁盘文件(temp_file)中的起始位置、记录数量等信息。 - Merge_chunk 和数据记录写入磁盘文件之后,排序缓冲区中的数据被清空,然后就可以写入其它待排序记录了,再次写满之后,缓冲区中的记录同样会进行排序,组成一个数据块,并把 Merge_chunk 和数据记录分别写入磁盘文件 chunk_file 和 temp_file。
- 读完符合 where 条件的所有记录之后,可能会生成多个数据块,对数据块进行 7 路归并排序,把 7 个小数据块合并成大数据块,直到合并得到的大数据块数量小于等于 15 个(
如果归并排序之前,数据块数量本身就小于等于 15 个,此步骤跳过
)。 - 最后,通过多路归并排序把小于等于 15 个数据块合并为最终的排序结果,写入磁盘文件(out_file)。
排序缓存介绍
排序缓冲区是内存
缓冲区,用于存放待排序记录。对于服务器来说,内存是稀缺资源,既然排序缓冲区在内存中,其大小必然要受到限制。
相关参数说明
-
sort_buffer_size:
- sort_buffer_size参数用于指定排序缓冲区的大小,以字节为单位。
- 该参数的默认值通常较小,例如256KB或512KB,但可以根据需要进行调整。
- 增大sort_buffer_size可以提高排序操作的性能,尤其是在需要排序大量数据时。
- 然而,设置过大的值可能会占用过多的内存资源,因此需要根据系统的可用内存和排序操作的需求进行权衡和调整。
- 需要注意的是,连接缓冲区的大小是
针对每个连接
的,所以对于系统中的所有连接都会生效。
-
max_sort_length 参数:
- max_sort_length 是一个全局参数,用于指定排序操作中允许的最大排序键长度。
- 默认值为 1024,表示每个排序键的最大长度为 1024 字节。
- 该参数的目的是限制排序操作所使用的内存量,以防止过多的内存消耗。
- 如果某个排序键的长度超过了 max_sort_length 的值,MySQL 将会使用临时文件进行排序,而不是在内存中进行。
- 增大 max_sort_length 可以允许排序更长的键,但也会导致更多的内存使用。
连接缓冲区(Join Buffer)
MySQL Join Buffer(连接缓冲区)是MySQL中用于执行连接操作(JOIN)的一种缓冲区。它用于存储连接操作中的中间结果,以加速查询的执行。
在执行连接操作时,MySQL会将连接的两个表中的数据进行匹配,并生成结果集。这个过程可能涉及到大量的读取和比较操作,而连接缓冲区的作用就是在内存中存储部分连接操作的中间结果,以减少磁盘I/O和重复的比较操作,从而提高性能。
相关参数
-
join_buffer_size:
-
这是连接缓冲区的大小,以字节为单位。
-
可以通过设置该参数来调整连接缓冲区的大小。
-
例如,可以使用以下命令设置连接缓冲区的大小为4MB:
sqlSET GLOBAL join_buffer_size = 4 * 1024 * 1024;
-
需要注意的是,连接缓冲区的大小是
针对每个连接
的,所以对于系统中的所有连接都会生效。
-
-
join_buffer_space_limit:
-
这是连接缓冲区的最大可用空间限制。
-
默认情况下,连接缓冲区的大小可以根据需要进行动态调整,直到达到join_buffer_size设置的值。
-
但是,可以通过设置join_buffer_space_limit参数来限制连接缓冲区的最大可用空间。
-
例如,可以使用以下命令设置连接缓冲区的最大可用空间为2GB:
iniSET GLOBAL join_buffer_space_limit = 2 * 1024 * 1024 * 1024;
-
JOIN查询方式
- Simple Nested-Loop Join
- Index Nested-Loop Join
- Block Nested-Loop Join(简单-索引-缓冲区)
查询缓存(Query Cache)
查询缓存(Query Cache)是一种用于缓存查询结果的机制,可以提高重复查询的性能。然而,自MySQL 5.7.20版本起,查询缓存功能已被弃用,并在MySQL 8.0版本中完全删除。这是因为查询缓存可能带来一些性能问题,如锁竞争和内存管理等方面的开销。
查询缓存用于缓存查询结果,以避免重复执行相同的查询。
- 优点:对于经常重复执行相同查询的应用程序,启用查询缓存可以显著提高性能。
- 缺点:查询缓存的效果在高并发环境下可能不佳,因为对表的更新操作会导致缓存的失效,还可能引入锁竞争和额外的开销。
参数设置
-
query_cache_type:
- 这个参数指定查询缓存的工作方式。
- 默认值为0,表示查询缓存被禁用。
- 设置为1时,表示查询缓存被启用,但只缓存使用了SQL_CACHE提示的查询。
- 设置为2时,表示查询缓存被启用,缓存所有不使用SQL_NO_CACHE提示的查询。
- 由于查询缓存功能已被弃用,因此在MySQL 8.0及更新版本中,这个参数设置不会产生任何效果。
-
query_cache_size:
- 这个参数指定查询缓存的大小,用于存储查询结果。
- 默认值为0,表示查询缓存被禁用。
- 可以设置为一个适当的值,以控制查询缓存使用的内存大小。
- 由于查询缓存功能已被弃用,因此在MySQL 8.0及更新版本中,这个参数设置不会产生任何效果。
日志缓冲区(Log Buffer)
日志缓冲区(Log Buffer)是MySQL中用于存储事务日志(Transaction Log)的缓冲区。它在数据库执行事务时起到关键的作用。
基本介绍
当在MySQL中对InnoDB表进行更改时,这些更改首先存储在InnoDB日志缓冲区的内存中,然后写入通常称为重做日志(redo logs)的InnoDB日志文件中。
redo日志缓冲区是内存存储区域,用于保存要写入磁盘上的日志文件的数据。日志缓冲区大小由innodb_log_buffer_size 变量定义,默认大小为16MB。
日志缓冲区的内容定期刷新到磁盘。较大的日志缓冲区可以运行大型事务,而无需在事务提交之前将重做日志数据写入磁盘。因此,如果有更新,插入或删除许多行的事务,则增加日志缓冲区的大小可以节省磁盘I/O。
innodb_flush_log_at_trx_commit :控制如何将日志缓冲区的内容写入并刷新到磁盘。
innodb_flush_log_at_timeout :控制日志刷新频率。
如果磁盘I/O导致性能问题,则需要观察事务,例如涉及许多BLOB条目的事务。只要InnoDB日志缓冲区已满,便会将其刷新到磁盘,因此增加缓冲区大小可以减少I/O。
临时表
MySQL中的临时表是在内存或磁盘上创建的临时数据结构,用于存储在查询执行期间产生的中间结果。对于内部临时表(Internal Temporary Tables),MySQL会尝试将其存储在内存中,以提高性能。
参数介绍
-
tmp_table_size:
tmp_table_size
参数定义了内部临时表的最大大小。- 当内部临时表的大小超过了该值时,MySQL将其存储在磁盘上而不是内存中。
- 默认值为16MB。
-
max_heap_table_size:
max_heap_table_size
参数定义了内存中堆表(Heap Table)的最大大小。- 堆表是一种特殊的内部临时表,使用内存作为存储引擎。
- 如果一个查询需要创建堆表,并且其大小超过了该值,MySQL将尝试使用磁盘上的临时表。
- 默认值为16MB。
-
tmpdir:
tmpdir
参数定义了MySQL服务器用于存储临时文件的目录。- 临时文件包括使用磁盘存储的临时表以及其他临时文件,如排序和临时文件。
- 如果未指定
tmpdir
,MySQL将使用系统默认的临时目录。 - 可以使用绝对路径或相对于数据目录的相对路径来设置
tmpdir
。
参考