从 MySQL 8.4 开始,此处讨论的用于引用多个 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
语句 (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