[InterDB] [著者HP] [PREVIOUS][UP]

Copyright @ 2009, Suzuki Hironobu @ InterDB





■2-11■ クエリキャッシュ(Query Cache)

バージョン 4.0.1から、クエリキャッシュ(Query Cache)機能がサポートされました。

クエリキャッシュとは、実行されたSELECT文の結果をキャッシュ(query_cache)に保存しておき、同じSELECT文が要求された場合は(検索を行わずに)キャッシュに保存されている結果を返す機能です(補足 1)。

なお、キャッシュされたデータに関連するテーブルが変更(UPDATE,INSERT,DELETE)された場合、クエリキャッシュ上の結果は削除されます。よって『テーブルが更新されたのに、古い(キャッシュの)結果が返る』といった心配は*無用*です。

メモリ領域の利用方法

検索結果はブロック単位(デフォルトは4[Kbyte])で保存します(補足 2)。
検索結果の保存には、クエリテキスト(SELECT文そのもの)を保存するために 1ブロック、結果を保存するために 1ブロック以上を使います。
さらに、SELECT文で使ったテーブル名を保存するために1ブロックが必要です(ただし、既にそのテーブル名が保存されていれば不要)。

具体的な例で説明します(【図.2-31】参照)。

図.2-31クエリキャッシュの動作

    (1)`SELECT * FROM t1'を実行すると、クエリテキスト``SELECT * FROM t1''を保存するために1ブロック、テーブル名`t1'を保存するために1ブロック、検索結果の保存に1ブロック(実際は結果行数に依存)、合計3ブロックを使う。

    (2)`SELECT * FROM t2'を実行すると、(1)と同様に合計3ブロックを使う(同様に、実際は結果行数に依存)。

    (3)`SELECT * FROM t2 WHERE id < 100'を実行すると、クエリテキスト``SELECT * FROM t2 WHERE id < 100''を保存するために1ブロック、検索結果の保存に1ブロック、計2ブロックを使う(同様に、実際は結果行数に依存)。テーブル名`t2'は既に保存されているので、ここでは保存しない。

    (4)`UPDATE t2 SET j = 1 WHERE i = 1'を実行すると、テーブルt2に関連するクエリテキストとデータとテーブル名がクエリキャッシュから削除される。この場合は(2)と(3)で保存した合計5ブロックのデータが削除される。

メモリ領域のフラグメントとデフラグメント

長期間MySQLサーバを運用していると、少しずつクエリキャッシュ領域がフラグメント化(分断化)されていきます。

具体例でフラグメントが起こる状況を示します(【図.2-32】参照)。

図.2-32 クエリキャッシュのフラグメント

    (1)現時点で、クエリ1〜3の検索結果がキャッシュ上に保存されている。
    (2)クエリ1のデータが削除され、3ブロックが空き状態となっている。
    (3)クエリ4は合計5ブロックを使用するため、先の空きブロックには入り切らず、別領域に保存される。

このようにして、徐々に空きブロックが増えていきます。

空きブロックを一掃する操作を`デフラグメント'といいます。クエリキャッシュのデフラグメントはFLUSH QUERY CACHE文で行います。

実際にFLUSH QUERY CACHE文を実行してみましょう(【図.2-33】参照)。

図.2-33 クエリキャッシュのデフラグメント

最初は空きブロックが3つありますが、デフラグメント後は空きブロックが2つ減少して(初期値)1になり、全体の使用ブロック数`Qcache_total_blocks'も解放された空きブロック数2だけ減少しています(36 → 34)。

mysql> SHOW STATUS LIKE 'Qcache_%_blocks';
+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| Qcache_free_blocks      | 3     |
| Qcache_total_blocks     | 36    |
+-------------------------+-------+
2 rowa in set (0.00 sec)

mysql> FLUSH QUERY CACHE;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW STATUS LIKE 'Qcache_%_blocks';
+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| Qcache_free_blocks      | 1     |
| Qcache_total_blocks     | 34    |
+-------------------------+-------+
2 rows in set (0.00 sec)


補足


(1)
【図.2-3】(問い合わせ処理の流れ)において、構文解析以前にクエリキャッシュにSQL文があるか否かを検査していることに注目してください。

(2)
1ブロックのデフォルトサイズ(4[Kbyte])はシステム変数`query_cache_min_res_unit'で設定します。



[PREVIOUS][UP]