High Performance MySQL Second Edition



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)

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操作。

(引用:High Performance MySQL 原書Figure 5-1 插圖)

定長:空間浪費
變長:需清理碎片
block 小: 鏈表超長,訪問大塊數據效率低。

另外發現 surfchen 的 MySQL的Query Cache 對這方面的內容描述也不錯,可以和本文互爲補充。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章