查詢緩存區(query cache)是Mysql 4.0版本後引入的一項功能,本意是提高SQL查詢性能,即把某些SQL查詢命令的結果存放在內存裡,當其他用戶再次執行一條完全相同的查詢命令 時,MySQL將會把緩存在內存裡的查詢結果直接發送給他,而不用再對數據庫表進行查詢。
但是並不是說查詢緩存區就只有優點,而沒有缺點,我舉個例子,一個項目裡如果是update, delete ,insert等數據庫操作比select操作更多,那我想覺得這時候就不適合開啟查詢緩存區的功能,為什麼呢,原因很簡單,查詢緩存區緩存的是查詢的結 果,如果數據庫表內容經常的改變,那很多查詢結果多必須從查詢緩存區裡刪除掉,特別是內存較小的系統,這樣的話,只會加劇數據庫的負擔。
基於 這一點,用不用開啟查詢緩存區的功能,查閱不少文檔後,總結幾條如下: 1. 就是查詢緩存區適合select 操作較多,而insert update delete操作較少的情況,並且重復的SQL查詢越多,效果越好。 2. 就是SQL查詢語句命令必須嚴格的相同,包括字母大小寫,空格,舉個例子
有這麼兩行查詢語句,select username,email from members order by username limit 10; Select username,email from members order by username limit 10; 咋看怎麼長的都一樣,而且查詢的結果也是一樣的,是的,沒錯,除 了“select”和“Select”一個字母大小寫的不同外,其他的都一樣,但是在Mysql內部,SQL分析器卻會把這兩條長的一樣的語句當作兩條不 同的語句,MySQL的確很傻很天真,嘿嘿,
這裡還要注意的是MySQL對數據庫和數據表是區分大小寫的,而對數據列是不區分大小寫的。 3. 就是select 命令裡不能含有一些特殊的函數,比如CUDATE(),NOW(),有這些函數在裡面,查詢緩存區幾乎不起作用,只會給系統帶來額外開銷。
查 詢緩存區的啟用如果 query_cache_size=0,那麼當前沒有開啟查詢緩存區
在my.cnf的 [MySQLd]配置段 query_cache_size =128M
query_cache_type = 1 (有三個值,分別是0,1,2)
qurey_cache_limit=128K;
意思是給啟用查詢緩存區並給查詢緩存區分 配128M的內存空間, 而且允許查詢的結果數據必須不大於128KB大小
query_cache_type為1,表示在SQL語句裡加上了 SQL_NO_CACHE關鍵字的,強制不緩存查詢結果。
query_cache_type為0,表示關閉SQL語句裡的SQL_CACHE和 SQL_NO_CACHE功能,也就是禁用查詢緩存功能。
query_cache_type為2,表示在SQL語句裡,只有包含著 SQL_CACHE的查詢才會進入查詢緩存區。下篇我將介紹下查詢緩存區的優化方法。查看查詢緩存區的相關變量:
MySQL> SHOW VARIABLES LIKE '%query_cache%';
+------------------------------+----------+
| Variable_name | Value |
+------------------------------+----------+
| have_query_cache | YES |
| query_cache_limit | 1048576 |
| query_cache_min_res_unit | 4096 |
| query_cache_size | 33554432 |
| query_cache_type | ON |
| query_cache_wlock_invalidate | OFF |
+------------------------------+----------+
6 rows in set (0.00 sec)
have_query_cache
是 否支持查詢緩存區 “YES”表是支持查詢緩存區query_cache_limit 可緩存的 Select查詢結果的最大值 1048576 byte /1024 = 1024kB 即最大可緩存的select查詢結果必須小於1024KBquery_cache_min_res_unit 每次給query cache結果分配內存的大小 默認是 4096 byte 也即 4kB 在這裡,我延伸三點重 要的東西 1.當查詢進行的時候,Mysql把查詢結果保存在qurey cache中,但是有時候要保存的結果比較大,超過了query_cache_min_res_unit的值 ,這時候MySQL將一邊檢索結果,一邊進行慢慢保存結果,所以,有時候並不是
把所有結果全部得到後再進行一次性保存,而是每次分配一塊 query_cache_min_res_unit 大小的內存空間保存結果集, mysql要進行多次內存分配的操作,而我們應該知道,頻繁操作內存都是要耗費時間的。 2. 內存碎片的產生。當一塊分配的內存沒有完全使用時,MySQL會把這塊內存Trim掉,把沒有使用的那部分歸還以重復利用。比如,第一次分配4KB,只用 了3KB,剩1KB,第二次連續操作,分配4KB,用了2KB,剩2KB,這兩次連續操作共剩下的1KB+2KB=3KB,不足以做個一個內存單元分配, 這時候,內存碎片便產生了。 3.內存塊的概念,先看下這個:
MySQL> show status like 'qcache%';
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_free_blocks | 5096 |
| Qcache_free_memory | 18964096 |
| Qcache_hits | 12192192 |
| Qcache_inserts | 3560370 |
| Qcache_lowmem_prunes | 17326 |
| Qcache_not_cached | 303599 |
| Qcache_querIEs_in_cache | 10201 |
| Qcache_total_blocks | 25937 |
+-------------------------+----------+
8 rows in set (0.00 sec)
Qcache_total_blocks 表 示所有的塊Qcache_free_blocks 表示未使用的塊 這個值比較大,那意味著,內存碎片比較多,用flush query cache清理後,
為被使用的塊其值應該為1或0 ,因為這時候所有的內存都做為一個連續的快在一起了:
MySQL> show status like 'qcache%';
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_free_blocks | 1 |
| Qcache_free_memory | 18539240 |
| Qcache_hits | 12192502 |
| Qcache_inserts | 3560515 |
| Qcache_lowmem_prunes | 17326 |
| Qcache_not_cached | 303607 |
| Qcache_querIEs_in_cache | 10318 |
| Qcache_total_blocks | 21081 |
+-------------------------+----------+
8 rows in set (0.00 sec)
其 他幾個狀態變量的意義:Qcache_free_memory 表示查詢緩存區現在還有多少的可 用內存
Qcache_hits 表示查詢緩存區的命中個數,也就是直接從查詢緩存區作出響應處理的查詢個數
Qcache_inserts 表示查詢緩存區此前總過緩存過多少條查詢命令的結果
Qcache_lowmem_prunes 表示查詢 緩存區已滿而從其中溢出和刪除的查詢結果的個數
Qcache_not_cached 表示沒有進入查詢緩 存區的查詢命令個數
Qcache_querIEs_in_cache 查詢緩存區當前緩存著多少條查詢命令的結果優化提示:
如果 Qcache_lowmem_prunes 值比較大,表示查詢緩存區大小設置太小,需要增大。
如果Qcache_free_blocks 較多,表示內存碎片較多,需要清理,flush query cache
根據我看的 《High Performance MySQL》中所述,關於query_cache_min_res_unit大小的調優
,書中給出了一個計算公式,可以供調優設置參考:
query_cache_min_res_unit = (query_cache_size - Qcache_free_memory) / Qcache_querIEs_in_cache 還 要注意一點的是,FLUSH QUERY CACHE 命令可以用來整理查詢緩存區的碎片,改善內存使用狀況,
但不會清理查詢緩存區的內容,這個 要和RESET QUERY CACHE相區別,不要混淆,後者才是清除查詢緩存區中
的所有的內容。 -------------------END--------------------