8.10.2.2 多个键缓存

对密钥缓存的共享访问可以提高性能,但不能完全消除会话之间的争用。他们仍在争夺 Management 对键高速缓存缓冲区的访问的控制结构。为了进一步减少密钥缓存访问争用,MySQL 还提供了多个密钥缓存。此功能使您可以将不同的 table 索引分配给不同的键高速缓存。

如果有多个键缓存,则服务器必须知道在处理给定MyISAMtable 的查询时要使用哪个缓存。默认情况下,所有MyISAMtable 索引都缓存在默认键缓存中。要将 table 索引分配给特定的键高速缓存,请使用CACHE INDEX语句(请参见第 13.7.6.2 节“ CACHE INDEX 语句”)。例如,以下语句将 tablet1t2t3的索引分配给名为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       |
+---------+--------------------+----------+----------+

可以通过使用SET GLOBAL参数设置语句设置其大小或使用服务器启动选项来创建CACHE INDEX语句中引用的键高速缓存。例如:

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_sizekeycache1是缓存变量名称,而key_buffer_size是缓存组件。有关用于引用结构化键缓存系统变量的语法的描述,请参见第 5.1.8.3 节“结构化的系统变量”

默认情况下,table 索引分配给服务器启动时创建的主(默认)键高速缓存。销毁键高速缓存时,分配给它的所有索引都将重新分配给默认键高速缓存。

对于繁忙的服务器,可以使用涉及三个关键缓存的策略:

  • “热”键高速缓存占用了分配给所有键高速缓存的 20%的空间。将其用于大量用于搜索但未更新的 table。

  • “冷”键高速缓存占用了分配给所有键高速缓存的 20%的空间。将此缓存用于中等大小的,经过大量修改的 table,例如临时 table。

  • “热”密钥缓存占用了密钥缓存空间的 60%。将此用作默认键缓存,默认情况下将其用于所有其他 table。

使用三个密钥缓存的好处之一是,访问一个密钥缓存结构不会阻止对其他密钥缓存结构的访问。访问分配给一个缓存的 table 的语句不会与访问分配给另一缓存的 table 的语句竞争。由于其他原因也会导致性能提升:

  • 热缓存仅用于检索查询,因此永远不会修改其内容。因此,每当需要将索引块从磁盘中拉入时,就无需先清除用于替换的高速缓存块的内容。

  • 对于分配给热缓存的索引,如果没有查询需要进行索引扫描,则很有可能与索引 B 树的非叶子节点相对应的索引块保留在缓存中。

  • 当更新的节点位于高速缓存中并且不需要首先从磁盘读取时,对临时 table 最频繁执行的更新操作将更快地执行。如果临时 table 的索引大小与冷键高速缓存的大小相当,则更新的节点位于高速缓存中的可能性很高。

CACHE INDEX语句在 table 和键高速缓存之间构建了关联,但是每次服务器重新启动时,该关联都会丢失。如果要使该关联在每次服务器启动时都生效,则一种实现方法是使用选项文件:包括配置密钥缓存的变量设置和一个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_cachecold_cache分配了几个 table:

CACHE INDEX db1.t1, db1.t2, db2.t3 IN hot_cache
CACHE INDEX db1.t4, db2.t5, db2.t6 IN cold_cache