从 MySQL 9.0 开始,这里讨论的用于引用多个 MyISAM
键缓存的复合部分结构化变量语法已弃用。
共享访问键缓存可提高性能,但不能完全消除会话之间的争用。它们仍然会争夺管理对键缓存缓冲区访问的控制结构。为了进一步减少键缓存访问争用,MySQL 还提供了多个键缓存。此功能使您可以将不同的表索引分配给不同的键缓存。
在存在多个键缓存的情况下,服务器必须知道在处理给定 MyISAM
表的查询时使用哪个缓存。默认情况下,所有 MyISAM
表索引都缓存在默认键缓存中。要将表索引分配给特定键缓存,请使用 CACHE INDEX
语句(参见 第 15.7.8.2 节,“CACHE INDEX 语句”)。例如,以下语句将表 t1
、t2
和 t3
中的索引分配给名为 hot_cache
的键缓存
mysql> CACHE INDEX t1, t2, t3 IN hot_cache;
+---------+--------------------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+---------+--------------------+----------+----------+
| test.t1 | assign_to_keycache | status | OK |
| test.t2 | assign_to_keycache | status | OK |
| test.t3 | assign_to_keycache | status | OK |
+---------+--------------------+----------+----------+
在 CACHE INDEX
语句中引用的键缓存可以通过设置其大小来创建,可以使用 SET GLOBAL
参数设置语句或使用服务器启动选项。例如
mysql> SET GLOBAL keycache1.key_buffer_size=128*1024;
要销毁键缓存,请将其大小设置为零
mysql> SET GLOBAL keycache1.key_buffer_size=0;
您无法销毁默认键缓存。任何尝试这样做都会被忽略
mysql> SET GLOBAL key_buffer_size = 0;
mysql> SHOW VARIABLES LIKE 'key_buffer_size';
+-----------------+---------+
| Variable_name | Value |
+-----------------+---------+
| key_buffer_size | 8384512 |
+-----------------+---------+
键缓存变量是具有名称和组件的结构化系统变量。对于 keycache1.key_buffer_size
,keycache1
是缓存变量名,key_buffer_size
是缓存组件。参见 第 7.1.9.5 节,“结构化系统变量”,了解用于引用结构化键缓存系统变量的语法的描述。
默认情况下,表索引分配给服务器启动时创建的主(默认)键缓存。当销毁键缓存时,分配给它的所有索引都会重新分配给默认键缓存。
对于繁忙的服务器,您可以使用涉及三个键缓存的策略
一个 “热” 键缓存,占用分配给所有键缓存的空间的 20%。将此用于用于搜索但未更新的表。
一个 “冷” 键缓存,占用分配给所有键缓存的空间的 20%。将此缓存用于中等大小、密集修改的表,例如临时表。
一个 “温” 键缓存,占用键缓存空间的 60%。将其用作默认键缓存,默认情况下用于所有其他表。
使用三个键缓存有利的一个原因是,访问一个键缓存结构不会阻止访问其他结构。访问分配给一个缓存的表的语句不会与访问分配给另一个缓存的表的语句竞争。性能提升还出于其他原因而发生
热缓存仅用于检索查询,因此其内容永远不会被修改。因此,每当需要从磁盘中拉取索引块时,无需先刷新所选用于替换的缓存块的内容。
对于分配给热缓存的索引,如果没有任何查询需要索引扫描,则索引 B 树的非叶子节点对应的索引块很可能保留在缓存中。
针对临时表执行的更新操作,当更新的节点在缓存中并且无需首先从磁盘中读取时,执行速度会快得多。如果临时表的索引大小与冷键缓存的大小相当,则更新的节点很可能在缓存中。
使用 CACHE INDEX
语句可以设置表和键缓存之间的关联关系,但这种关联关系在服务器每次重启时都会丢失。如果您希望该关联关系在服务器每次启动时生效,可以使用选项文件来实现:在选项文件中包含配置键缓存的变量设置,以及一个 init_file
系统变量,该变量指定包含要执行的 CACHE INDEX
语句的文件。例如
key_buffer_size = 4G
hot_cache.key_buffer_size = 2G
cold_cache.key_buffer_size = 2G
init_file=/path/to/data-directory/mysqld_init.sql
在服务器每次启动时,mysqld_init.sql
文件中的语句都会被执行。该文件应包含每行一个 SQL 语句。以下示例将多个表分别分配给 hot_cache
和 cold_cache
CACHE INDEX db1.t1, db1.t2, db2.t3 IN hot_cache
CACHE INDEX db1.t4, db2.t5, db2.t6 IN cold_cache