ウィリアムのいたずらの、まちあるき、たべあるき

ウィリアムのいたずらが、街歩き、食べ物、音楽等の個人的見解を主に書くブログです(たま~にコンピューター関係も)

MySQLのクエリーキャッシュが効かない場合

2012-03-01 12:24:15 | トピックス
MySQLで、同じSELECT文を発行する場合、クエリーキャッシュを使うと早くなることがある。
クエリーキャッシュは、my.cnf(my.ini)でも設定できるし、mysqlのコマンドとしても設定できる。




■ 設定
今回は、mysqlのコマンドで、以下のように行う。

SET GLOBAL query_cache_size = 100000;


■ 確認
これで、

SHOW VARIABLES LIKE 'have_query_cache';

でYES

SHOW VARIABLES LIKE 'query_cache%';


query_cache_sizeにいくつかの値が設定されている
(100000と設定しても100000にはならない)


SHOW STATUS LIKE 'Qcache%';



Qcache_hits       (ヒットした件数)
Qcache_not_cached    (ヒットしなかった件数)
Qcache_queries_in_cache  (キャッシュ内のクエリ数)

等が表示される(他にも表示される)。




■効かない条件

 しかし、このクエリーキャッシュは、いくつかの効かない条件がある。

http://dev.mysql.com/doc/refman/5.1/ja/query-cache-how.html

には、以下のようなものがあげられている。

・準備されたステートメント (準備文)
・クエリが外部クエリのサブクエリである場合
・Stored プロシージャ、Stored 関数、トリガ、イベントなどのボディ内で実行したクエリ

Zendの古いバージョンなどだと、クエリーキャッシュが効かないとかいうのは、
「準備されたステートメント」=PreparedStatementの問題。

で、ここから本題。
これ以外のケースではまったので・・・

データベース名に-を含むもの、たとえば、te-st1とかは、単純には作れない。
ところが、`te-st1`とかして、名前を指定すると作れる。
この場合、データベースの中に、テーブルは作れ、そのデータベース内に
入れば、SELECTはできるけど・・・

クエリーキャッシュは効かない。




■例
(以下、>は、本当は半角)
いま、test2とte-st1というDBに、
test1というまったく同じテーブルがあったとき、
mysql> reset query cache;
Query OK, 0 rows affected (0.00 sec)


でキャッシュをリセット後

mysql> SHOW STATUS LIKE 'Qcache%';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| Qcache_free_blocks | 1 |
| Qcache_free_memory | 90736 |
| Qcache_hits | 2176 |
| Qcache_inserts | 792 |
| Qcache_lowmem_prunes | 599 |
| Qcache_not_cached | 1184 |
| Qcache_queries_in_cache | 0 |
| Qcache_total_blocks | 1 |
+-------------------------+-------+
8 rows in set (0.00 sec)

mysql> use test2;
Database changed
mysql> select * from test1;
+------+--------+
| id | mydata |
+------+--------+
| 1 | abc |
+------+--------+
1 row in set (0.00 sec)

mysql> select * from test1;
+------+--------+
| id | mydata |
+------+--------+
| 1 | abc |
+------+--------+
1 row in set (0.00 sec)

mysql> select * from test1;
+------+--------+
| id | mydata |
+------+--------+
| 1 | abc |
+------+--------+
1 row in set (0.00 sec)

mysql> SHOW STATUS LIKE 'Qcache%';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| Qcache_free_blocks | 1 |
| Qcache_free_memory | 89200 |
| Qcache_hits | 2178 |
| Qcache_inserts | 793 |
| Qcache_lowmem_prunes | 599 |
| Qcache_not_cached | 1185 |
| Qcache_queries_in_cache | 1 |
| Qcache_total_blocks | 4 |
+-------------------------+-------+
8 rows in set (0.00 sec)



というように、test2のデータベースを使って、
test1を3回検索すると、
Qcache_queries_in_cacheと、 Qcache_hits の数があがる
(その前に何回もテストしているので、0ではないけど)

ところが、この直後、te-st1のDBに対して、同じことをやっても、


mysql> use `te-st1`;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select * from test1;
+------+--------+
| id | mydata |
+------+--------+
| 1 | abc |
+------+--------+
1 row in set (0.00 sec)

mysql> select * from test1;
+------+--------+
| id | mydata |
+------+--------+
| 1 | abc |
+------+--------+
1 row in set (0.00 sec)

mysql> select * from test1;
+------+--------+
| id | mydata |
+------+--------+
| 1 | abc |
+------+--------+
1 row in set (0.00 sec)

mysql> SHOW STATUS LIKE 'Qcache%';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| Qcache_free_blocks | 1 |
| Qcache_free_memory | 89200 |
| Qcache_hits | 2178 |
| Qcache_inserts | 793 |
| Qcache_lowmem_prunes | 599 |
| Qcache_not_cached | 1189 |
| Qcache_queries_in_cache | 1 |
| Qcache_total_blocks | 4 |
+-------------------------+-------+
8 rows in set (0.00 sec)



というように、 Qcache_hits は上がらず、 Qcache_not_cachedがあがる。
つまり、キャッシュされてない。


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする