MySql Query Cache 和 Oracle Query Cache 是不同的, Oracle Query Cache 是緩存執行計劃的,而MySQL Query Cache 不緩存執行計劃而是整個結果集。緩存整個結果集的好處不言而喻,但由於緩存的是結果集因此Query必須是完全一樣的,這樣帶來的後果就是平均 Hit Rate 命中率一般不會太高。 Query Cache 對於一些小型應用程序或者數據表的數據量不大的情況下效果是最為明顯的。
作為一個新的特性,MySQL Query Cache 有什麼特典和局限呢? 咱一個一個來說:
1、Cache 機制對應用程序是透明的。在應用程序中只是改變查詢語句的語義,也能得到緩存中的查詢結果集。如果你沒有使用 query_cache_wlock_invalidate=ON 來提示MySQL 鎖表將要進行寫操作,那麼此時的查詢即使表在鎖Lock狀態下或者預備更新的狀態下,仍然可以從緩存中獲得結果集;
2、只緩存整個查詢結果集,即對子查詢,內聯視圖和部分UNION的查詢是不緩存的;
3、緩存機制工作在Packet 級別,第二項的只緩存整個查詢結果集就是因為局限於這個機制的原因。由於沒有額外的轉換和處理,所以保證緩存結果集返回能夠非常快;
4、緩存處理在解析查詢前進行,保證緩存高性能的一個原因就是查詢緩存在執行查詢解析前先查找是否已經存在緩存,如果已經存在查詢緩存,則直接返回結果集。
5、查詢必須絕對完全同,由於在查找緩存是否存在前不進行查詢解析( Query Parser )所以查詢並沒有經過規范化處理(Normalized),因此緩存查找的過程是按字節順序進行的 ( Byte by byte )。更具體點說吧:在每次查詢時包不同的注釋、多余的空格以及大小寫不同等等,都不會指向同一個緩存結果集。
6、只有 SELECT 語句被緩存。 插入、刪除、更新當然不需要進行緩存了,同時 SHOW 命令和 存儲過程 stored procedure (包括存儲過程中的SELECT)也不會進入緩存結果集。
7、空格和注釋不要出現在查詢語句的最前面,當查找緩存時第一個字幕如果不是"S" ,就會停止查詢緩存結果集了。第5、6項已經解釋過了;
8、不支持預備查詢 prepared statement 和 游標 cursors 。 ( ? )
9、或許不支持事務處理。(?)
10、查詢結果必須完全一致,才能進入緩存結果集。比如:查詢語句中有 UUID , RAND , CONNECTION_ID 等會動態改變查詢結果集的函數,都不會進入緩存結果集的;
11、查詢緩存失效的粒度級別的是表,當表被修改時,所有與改表相關的緩存立即失效( invalidation )。
12、過長時間的查詢緩存容易造成碎片 fragmentation ,這一點和Windows的磁盤管理的碎片整理類似,長時間查詢緩存產生的碎片對執行效率有一定影響。可以把查詢緩存碎片看作是是查詢緩存可用內存(Qcache_free_memory)的塊(Qcache_free_blocks )。FLUSH QUERY CACHE 命令可以削除這種情況。
13、設定適當大小的查詢緩存用的內存,由於前面提到的一些原因,一般情況下MySQL 的查詢緩存機制對內存的需求不可能無限增長,因此設定一個適當的查詢緩存內存值是比較經濟的做法。可以通過查看 Qcache_free_memory 和 Qcache_lowmem_prunes 的狀態來進行適當設置。
14、查詢緩存的運行模式,默認情況下開啟緩存後MySQL 的緩存機制對全局的有效,如果你只想對特定的查詢語句使用緩存,可以通過把 query_cache_type 設定為 “DEMAND” 並且在查詢語句中加入: SQL_CACHE 來進行,比如:SELECT SQL_CACHE DomoloSEOHelper from domolo where author='tianchunfeng' 。
上面為你介紹了 Mysql 查詢緩存的一些基本特點,那麼如何監控MySQL 查詢緩存的運行時狀態呢?比如監控查詢緩存的命中率,調節查詢緩存的內存大小等等數據。
可以使用下面的命令:
MySQL> show status like ‘Qcache%’;
輸出:
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_free_blocks | 1 |
| Qcache_free_memory | 16766912 |
| Qcache_hits | 3 |
| Qcache_inserts | 1 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 6 |
| Qcache_querIEs_in_cache | 1 |
| Qcache_total_blocks | 4 |
+-------------------------+----------+具體解釋參考: the MySQL Query Cache documentation。