對鍵高速緩沖的共享訪問可以提高性能但不能完全消除線程之間的竟爭。它們仍然競爭對鍵高速緩沖緩存區的訪問進行管理的控制結構。為了進一步降低 鍵高速緩沖訪問竟爭,MySQL 5.1還提供了多個鍵高速緩沖,允許你為不同的鍵高速緩沖分配不同的表索引。
有多個鍵高速緩沖時,當為給定的MyISAM表處理查詢時,服務器必須知道使用哪個緩存。默認情況,所有MyISAM表索引被緩存到默認 鍵高速緩沖中。要想為具體鍵高速緩沖分配表索引,應使用CACHE INDEX語句(參見13.5.5.1節,“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 |
+---------+--------------------+----------+----------+
可以用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_size,keycache1是緩存變量名,key_buffer_size是緩存組件。關于引用結構式 鍵高速緩沖系統變量所使用的語法的描述,參見9.4.1節,“結構式系統變量”
默認情況下,表索引被分配給服務器啟動時創建的主要(默認)鍵高速緩沖。當 鍵高速緩沖被刪除后,所有分配給它的索引被重新分配給默認鍵高速緩沖。
對于一個忙的服務器,我們建議采用使用三個鍵高速緩沖的策略:
· 占用為所有鍵高速緩沖分配的空間的20%的“熱”鍵高速緩沖。該緩存用于頻繁用于搜索但沒有更新的表。
· 占用為所有鍵高速緩沖分配的空間的20%的“冷”鍵高速緩沖。該緩存用于中等大小、大量修改的表,例如臨時表。
· 占用鍵高速緩沖空間的20%的“溫”鍵高速緩沖。使用它作為默認 鍵高速緩沖,默認情況被所有其它表使用。
使用3個鍵高速緩沖有好處的一個原因是對一個鍵高速緩沖結構的訪問不會阻擋對其它的訪問。訪問分配給一個緩存的表的查詢不會與訪問分配給其它緩存的表的查詢競爭。由于其它原因也會提高性能:
· 熱緩存只用于檢索查詢,因此其內容決不會被修改。結果是,無論何時需要從硬盤上拉入索引塊,選擇用于替換的緩存塊的內容不需要先刷新。
· 對于分配給熱緩存的索引,如果沒有查詢需要索引掃描,很有可能對應索引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 a.t1, a.t2, b.t3 IN hot_cache
CACHE INDEX a.t4, b.t5, b.t6 IN cold_cache