《Mysql實例MySQL的查詢緩存機制基本學習教程》要點:
本文介紹了Mysql實例MySQL的查詢緩存機制基本學習教程,希望對您有用。如果有疑問,可以聯系我們。
MYSQL應用MySQL緩存機制簡單的說就是緩存sql文本及查詢結果,如果運行相同的sql,服務器直接從緩存中取到結果,而不需要再去解析和執行sql.如果表更改 了,那么使用這個表的所有緩沖查詢將不再有效,查詢緩存值的相關條目被清空.更改指的是表中任何數據或是結構的改變,包括INSERT、UPDATE、 DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE等,也包括那些映射到改變了的表的使用MERGE表的查詢.顯然,這對于頻繁更新的表,查詢緩存是不適合的,而對于一些不常改變數據且有 大量相同sql查詢的表,查詢緩存會節約很大的性能.
MYSQL應用命中條件
MYSQL應用緩存存在一個hash表中,通過查詢SQL,查詢數據庫,客戶端協議等作為key.在判斷是否命中前,MySQL不會解析SQL,而是直接使用SQL去查詢緩存,SQL任何字符上的不同,如空格,注釋,都會導致緩存不命中.
MYSQL應用如果查詢中有不確定數據,例如CURRENT_DATE()和NOW()函數,那么查詢完畢后則不會被緩存.所以,包含不確定數據的查詢是肯定不會找到可用緩存的
MYSQL應用?
MYSQL應用工作流程
MYSQL應用1. 服務器接收SQL,以SQL和一些其他條件為key查找緩存表(額外性能消耗)
MYSQL應用2. 如果找到了緩存,則直接返回緩存(性能提升)
MYSQL應用3. 如果沒有找到緩存,則執行SQL查詢,包括原來的SQL解析,優化等.
MYSQL應用4. 執行完SQL查詢結果以后,將SQL查詢結果存入緩存表(額外性能消耗)
MYSQL應用
緩存失效
MYSQL應用當某個表正在寫入數據,則這個表的緩存(命中檢查,緩存寫入等)將會處于失效狀態.在Innodb中,如果某個事務修改了表,則這個表的緩存在事務提交前都會處于失效狀態,在這個事務提交前,這個表的相關查詢都無法被緩存.
MYSQL應用?
MYSQL應用緩存的內存管理
MYSQL應用緩存會在內存中開辟一塊內存(query_cache_size)來維護緩存數據,其中有大概40K的空間是用來維護緩存的元數據的,例如空間內存,數據表和查詢結果的映射,SQL和查詢結果的映射等.
MYSQL應用MySQL將這個大內存塊分為小的內存塊(query_cache_min_res_unit),每個小塊中存儲自身的類型,大小和查詢結果數據,還有指向前后內存塊的指針.
MYSQL應用MySQL需要設置單個小存儲塊的大小,在SQL查詢開始(還未得到結果)時就去申請一塊空間,所以即使你的緩存數據沒有達到這個大小,也需要用這個大小的數據塊去存(這點跟Linux文件系統的Block一樣).如果結果超出這個內存塊的大小,則需要再去申請一個內存塊.當查詢完成發現申請的內存塊有富余,則會將富余的空間釋放掉,這就會造成內存碎片問題,見下圖
MYSQL應用
MYSQL應用此處查詢1和查詢2之間的空白部分就是內存碎片,這部分空閑內存是有查詢1查詢完以后釋放的,假設這個空間大小小于MySQL設定的內存塊大小,則無法再被使用,造成碎片問題
MYSQL應用在查詢開始時申請分配內存Block需要鎖住整個空閑內存區,所以分配內存塊是非常消耗資源的.注意這里所說的分配內存是在MySQL初始化時就開辟的那塊內存上分配的.
MYSQL應用?
MYSQL應用緩存的使用時機
MYSQL應用衡量打開緩存是否對系統有性能提升是一個很難的話題
MYSQL應用1. 通過緩存命中率判斷, 緩存命中率 = 緩存命中次數 (Qcache_hits) / 查詢次數 (Com_select)
MYSQL應用2. 通過緩存寫入率, 寫入率 = 緩存寫入次數 (Qcache_inserts) / 查詢次數 (Qcache_inserts)
MYSQL應用3. 通過 命中-寫入率 判斷, 比率 = 命中次數 (Qcache_hits) / 寫入次數 (Qcache_inserts), 高性能MySQL中稱之為比較能反映性能提升的指數,一般來說達到3:1則算是查詢緩存有效,而最好能夠達到10:1
MYSQL應用?
MYSQL應用緩存配置參數
MYSQL應用1. query_cache_type: 是否打開緩存
MYSQL應用可選項
MYSQL應用1) OFF: 關閉
MYSQL應用2) ON: 總是打開
MYSQL應用3) DEMAND: 只有明確寫了SQL_CACHE的查詢才會吸入緩存
MYSQL應用?
MYSQL應用2. query_cache_size: 緩存使用的總內存空間大小,單位是字節,這個值必須是1024的整數倍,否則MySQL實際分配可能跟這個數值不同(感覺這個應該跟文件系統的blcok大小有關)
MYSQL應用?
MYSQL應用3. query_cache_min_res_unit: 分配內存塊時的最小單位大小
MYSQL應用?
MYSQL應用4. query_cache_limit: MySQL能夠緩存的最大結果,如果超出,則增加 Qcache_not_cached的值,并刪除查詢結果
MYSQL應用?
MYSQL應用5. query_cache_wlock_invalidate: 如果某個數據表被鎖住,是否仍然從緩存中返回數據,默認是OFF,表示仍然可以返回
MYSQL應用?
MYSQL應用GLOBAL STAUS 中 關于 緩存的參數解釋:
MYSQL應用Qcache_free_blocks: 緩存池中空閑塊的個數
MYSQL應用Qcache_free_memory: 緩存中空閑內存量
MYSQL應用Qcache_hits: 緩存命中次數
MYSQL應用Qcache_inserts: 緩存寫入次數
MYSQL應用Qcache_lowmen_prunes: 因內存不足刪除緩存次數
MYSQL應用Qcache_not_cached: 查詢未被緩存次數,例如查詢結果超出緩存塊大小,查詢中包含可變函數等
MYSQL應用Qcache_queries_in_cache: 當前緩存中緩存的SQL數量
MYSQL應用Qcache_total_blocks: 緩存總block數
MYSQL應用?
MYSQL應用減少碎片策略
MYSQL應用1. 選擇合適的block大小
MYSQL應用2. 使用 FLUSH QUERY CACHE 命令整理碎片.這個命令在整理緩存期間,會導致其他連接無法使用查詢緩存
MYSQL應用PS: 清空緩存的命令式 RESET QUERY CACHE
MYSQL應用?
MYSQL應用查詢緩存問題分析
MYSQL應用
MYSQL應用InnoDB與查詢緩存
MYSQL應用Innodb會對每個表設置一個事務計數器,里面存儲當前最大的事務ID.當一個事務提交時,InnoDB會使用MVCC中系統事務ID最大的事務ID跟新當前表的計數器.
MYSQL應用只有比這個最大ID大的事務能使用查詢緩存,其他比這個ID小的事務則不能使用查詢緩存.
MYSQL應用另外,在InnoDB中,所有有加鎖操作的事務都不使用任何查詢緩存
MYSQL應用查詢必須是完全相同的(逐字節相同)才能夠被認為是相同的.另外,同樣的查詢字符串由于其它原因可能認為是不同的.使用不同的數據庫、不同的協議版本或者不同 默認字符集的查詢被認為是不同的查詢并且分別進行緩存.
MYSQL應用下面sql查詢緩存認為是不同的:
MYSQL應用
SELECT * FROM tbl_name
Select * from tbl_name
MYSQL應用?
MYSQL應用查詢緩存相關參數
MYSQL應用
mysql> SHOW VARIABLES LIKE '%query_cache%';
MYSQL應用
+------------------------------+---------+
| Variable_name | Value |
+------------------------------+---------+
| have_query_cache | YES | --查詢緩存是否可用
| query_cache_limit | 1048576 | --可緩存具體查詢結果的最大值
| query_cache_min_res_unit | 4096 |
| query_cache_size | 599040 | --查詢緩存的大小
| query_cache_type | ON | --阻止或是支持查詢緩存
| query_cache_wlock_invalidate | OFF |
+------------------------------+---------+
MYSQL應用下面是一個簡單的MySQL查詢緩存機制例子:
MYSQL應用
[mysql@csdba1850 ~]$ mysql -u root -p
MYSQL應用
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.0.45-community MySQL Community Edition (GPL)
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
MYSQL應用?
MYSQL應用
mysql> set global query_cache_size = 600000; --設置緩存內存
MYSQL應用
Query OK, 0 rows affected (0.00 sec)
MYSQL應用?
MYSQL應用
mysql> set session query_cache_type = ON; --開啟查詢緩存
MYSQL應用
Query OK, 0 rows affected (0.00 sec)
MYSQL應用
mysql> use test
MYSQL應用
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應用
mysql> show tables;
MYSQL應用
+----------------+
| Tables_in_test |
+----------------+
| animals |
| person |
+----------------+
5 rows in set (0.00 sec)
mysql> select count(*) from animals;
+----------+
| count(*) |
+----------+
| 6 |
+----------+
1 row in set (0.00 sec)
--Qcache_hits表示sql查詢在緩存中命中的累計次數,是累加值.
MYSQL應用
mysql> SHOW STATUS LIKE 'Qcache_hits';
MYSQL應用
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Qcache_hits | 0 | --0次
+---------------+-------+
8 rows in set (0.00 sec)
mysql> select count(*) from animals;
+----------+
| count(*) |
+----------+
| 6 |
+----------+
1 row in set (0.00 sec)
MYSQL應用?
MYSQL應用
mysql> SHOW STATUS LIKE 'Qcache%';
MYSQL應用?
MYSQL應用
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Qcache_hits | 1 | --表示sql在緩存中直接得到結果,不需要再去解析
+---------------+-------+
8 rows in set (0.00 sec)
MYSQL應用?
MYSQL應用
mysql> select count(*) from animals;
MYSQL應用
+----------+
| count(*) |
+----------+
| 6 |
+----------+
1 row in set (0.00 sec)
MYSQL應用?
MYSQL應用
mysql> select count(*) from animals;
MYSQL應用
+----------+
| count(*) |
+----------+
| 6 |
+----------+
1 row in set (0.00 sec)
MYSQL應用?
MYSQL應用
mysql> SHOW STATUS LIKE 'Qcache_hits';
MYSQL應用
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Qcache_hits | 3 | --上面的sql也是是從緩存中直接取到結果
+---------------+-------+
1 row in set (0.00 sec)
MYSQL應用
mysql> insert into animals select 9,'testsds' ; --插入數據后,跟這個表所有相關的sql緩存就會被清空掉
MYSQL應用
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
MYSQL應用
mysql> select count(*) from animals;
MYSQL應用
+----------+
| count(*) |
+----------+
| 7 |
+----------+
1 row in set (0.00 sec)
MYSQL應用
mysql> SHOW STATUS LIKE 'Qcache_hits';
MYSQL應用
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Qcache_hits | 3 | --還是等于3,說明上一條sql是沒有直接從緩存中直接得到的
+---------------+-------+
1 row in set (0.00 sec)
MYSQL應用?
MYSQL應用
mysql> select count(*) from animals;
MYSQL應用
+----------+
| count(*) |
+----------+
| 7 |
+----------+
1 row in set (0.00 sec)
MYSQL應用?
MYSQL應用
mysql> SHOW STATUS LIKE 'Qcache_hits';
MYSQL應用
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Qcache_hits | 4 |
+---------------+-------+
1 row in set (0.00 sec)
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/4872.html