mysql select緩存使用詳解

mysql Query Cache 默認爲打開。從某種程度能夠提升查詢的效果,可是未必是最優的解決方案,若是有的大量的修改和查詢時,因爲修改形成的cache失效,會給服務器形成很大的開銷,能夠經過query_cache_type【0(OFF)1(ON)2(DEMAND)】來控制緩存的開關.mysql

須要注意的是mysql query cache 是對大小寫敏感的,由於Query Cache 在內存中是以 HASH 結構來進行映射,HASH 算法基礎就是組成 SQL 語句的字符,因此 任何sql語句的改變從新cache,這也是項目開發中要創建sql語句書寫規範的緣由吧算法

1. 什麼時候cache
a) mysql query cache內容爲 select 的結果集, cache 使用完整的 sql 字符串作 key, 並區分大小寫,空格等。即兩個sql必須徹底一致纔會致使cache命中。
b) prepared statement永遠不會cache到結果,即便參數徹底同樣。聽說在 5.1 以後會獲得改善。
c) where條件中如包含了某些函數永遠不會被cache, 好比current_date, now等。
d) date 之類的函數若是返回是以小時或天級別的,最好先算出來再傳進去。
select * from foo where date1=current_date -- 不會被 cache
select * from foo where date1='2008-12-30' -- 被cache, 正確的作法
e) 太大的result set不會被cache (< query_cache_limit)sql

2. 什麼時候invalidate
a) 一旦表數據進行任何一行的修改,基於該表相關cache當即所有失效。
b) 爲何不作聰明一點判斷修改的是否cache的內容?由於分析cache內容太複雜,服務器須要追求最大的性能。數據庫

3. 性能
a) cache 未必全部場合老是會改善性能
當有大量的查詢和大量的修改時,cache機制可能會形成性能降低。由於每次修改會致使系統去作cache失效操做,形成不小開銷。
另外系統cache的訪問由一個單一的全局鎖來控制,這時候大量>的查詢將被阻塞,直至鎖釋放。因此不要簡單認爲設置cache一定會帶來性能提高。
b) 大result set不會被cache的開銷
太大的result set不會被cache, 但mysql預先不知道result set的長度,因此只能等到reset set在cache添加到臨界值 query_cache_limit 以後纔會簡單的把這個cache 丟棄。這並非一個高效的操做。若是mysql status中Qcache_not_cached太大的話, 則可對潛在的大結果集的sql顯式添加 SQL_NO_CACHE 的控制。
query_cache_min_res_unit = (query_cache_size – Qcache_free_memory) / Qcache_queries_in_cache緩存

4. 內存池使用
mysql query cache 使用內存池技術,本身管理內存釋放和分配,而不是經過操做系統。內存池使用的基本單位是變長的block, 一個result set的cache經過鏈表把這些block串起來。由於存放result set的時候並不知道這個resultset最終有多大。block最短長度爲 query_cache_min_res_unit, resultset 的最後一個block會執行trim操做。服務器


Query Cache 在提升數據庫性能方面具備很是重要的做用。函數

其設定也很是簡單,僅須要在配置文件寫入兩行: query_cache_type 和 query_cache _size,並且 MySQL 的 query cache 很是快!並且一旦命中,就直接發送給客戶端,節約大量的 CPU 時間。性能

固然,非 SELECT 語句對緩衝是有影響的,它們可能使緩衝中的數據過時。一個 UPDATE 語句引發的部分表修改,將致使對該表全部的緩衝數據失效,這是 MySQL 爲了平衡性能而沒有采起的措施。由於,若是每次 UPDATE 須要檢查修改的數據,而後撤出部分緩衝將致使代碼的複雜度增長。spa

 query_cache_type 0 表明不使用緩衝, 1 表明使用緩衝,2 表明根據須要使用。操作系統

設置 1 表明緩衝永遠有效,若是不須要緩衝,就須要使用以下語句:

 代碼以下 複製代碼

SELECT SQL_NO_CACHE * FROM my_table WHERE ...

若是設置爲 2 ,須要開啓緩衝,能夠用以下語句:

 代碼以下 複製代碼

SELECT SQL_CACHE * FROM my_table WHERE ...

用 SHOW STATUS 能夠查看緩衝的狀況:

 代碼以下 複製代碼

mysql> show status like 'Qca%';
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_queries_in_cache | 8 |
| Qcache_inserts | 545875 |
| Qcache_hits | 83951 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 2343256 |
| Qcache_free_memory | 33508248 |
| Qcache_free_blocks | 1 |
| Qcache_total_blocks | 18 |
+-------------------------+----------+
8 rows in set (0.00 sec)

若是須要計算命中率,須要知道服務器執行了多少 SELECT 語句:

 代碼以下 複製代碼

mysql> show status like 'Com_sel%';
+---------------+---------+
| Variable_name | Value |
+---------------+---------+
| Com_select | 2889628 |
+---------------+---------+
1 row in set (0.01 sec)

在本例中, MySQL 命中了 2,889,628 條查詢中的 83,951 條,並且 INSERT 語句只有 545,875 條。所以,它們二者的和和280萬的總查詢相比有很大差距,所以,咱們知道本例使用的緩衝類型是 2 。

而在類型是 1 的例子中, Qcache_hits 的數值會遠遠大於 Com_select

相關文章
相關標籤/搜索