<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## Query Cache背景 Query Cache在其他數據庫里面也稱為結果集緩存。顧名思義,它的目的是將SELECT語句與其返回結果緩存到Query Cache中,如果重復執行相同的SELECT語句的話,我們可以跳過MySQL的解析、優化、執行階段,將SELECT的查詢結果直接返回到客戶端,加速SELECT語句的執行。 ## Query Cache中的主要數據結構 | Query_cache | 對整個Query Cache進行管理,負責提供接口供Server調用。 | |---|---|---| | Query_cache_block | Query Cache中的所有存儲都是以Query_cache_block來組織的。每一個Query_cache_block的格式都是Block_header + data. | | Query_cache_table | 用來記錄單個數據表的Block_header。 | | Query_cache_block_table | 用來存儲與Query相關的數據表的Block_header。每一個數據表都有一個獨立的Query_cache_block_table結構對應。與Query_cache_table的區別是,所有Query使用的同一個數據表對應同一個Query_cache_table。 | | Query_cache_query | 用來記錄Query的Block_header。 | | Query_cache_result | 用來記錄結果集的Block_header。 | | Query_cache_memory_bin | 用來管理Query Cache的內存使用,Query Cache的整體內存被劃分為多個bins。該結構在Query Cache初始化的過程中完成。請參考下面Query Cache內存初始化部分。 | | Query_cache_memory_bin_step | 用來輔助初始化Query_cache_memory_bins,記錄內存管理的每一層的bins內存分配的大小。請參考下面Query Cache內存初始化部分。 | | Query_cache_query_flags | 用來記錄影響Query返回結果的環境變量,比如sql_mode,字符集,time_zone等。 | ## Query cache的存儲結構 Query cache中是利用Query_cache_block對象進行存儲的,存儲結構如下圖: ~~~ +----------------------------------------------------------------------------+ | Block header | +----------------------------------------------------------------------------+ | Table of database table lists | +----------------------------------------------------------------------------+ | Type depended header | +----------------------------------------------------------------------------+ | Data ... | +----------------------------------------------------------------------------+ ~~~ 說明: * Block header:指的就是Query_cache_block這個結構體自身需要存儲的一些信息。詳細信息可以參考sql/sql_cache.h中的結構體說明。 * Table of database table lists:這部分是用來記錄與Query相關的所有數據表header信息(Query_cache_block_table結構)。對于一條Query來說,每個相關的數據表都有一個這樣的header信息。而對于結果集數據塊來說,這部分不包含數據。 * Type depended header :這部分用來記錄依賴于該Block的具體對象header,比如是Query_cache_query還是Query_cache_result。 * Data:顧名思義,就是記錄我們當前存儲對象的數據信息。 ## Query cache的內存管理 Query cache依靠自己對內存進行管理。當用戶調整query_cache_size系統參數時,Query cache會自動的修改內存大小。 ### Query cache內存的初始化 Query cache的內存初始化包含兩個部分: 1. 一次性申請query_cache_size大小的內存空間。 2. 初始化內存管理方式。 Query cache的內存管理方式如下圖所示: ![](https://box.kancloud.cn/2016-07-22_5791a6c85710d.jpg) 說明: Query cache對于整個內存的管理是將整個內存塊劃分多層大小不同的多個`query_cache_memory_bins`(簡稱bins)。具體的層數由`query_cache_memory_bin_steps`?(簡稱steps)確定,steps是動態根據`query_mem_size`確定的,如何確定steps請參考`Query_cache::init_cache`。第N層的bins數量是由(前N-1層bins數量總和 + QUERY_CACHE_MEM_BIN_PARTS_INC) * QUERY_CACHE_MEM_BIN_PARTS_MUL 確定的。`QUERY_CACHE_MEM_BIN_PARTS_INC`和`QUERY_CACHE_MEM_BIN_PARTS_MUL`是定義的控制每一層bins增量的兩個宏。 ### Query cache內存的分配 Query cache剛初始化后,整個內存作為一個大的free_block。當需要申請新的數據塊時,Query cache首先尋找大小最為接近的bins進行匹配,判斷bins中有沒有free_block。如果有則使用;如果沒有則從其上一個bins中尋找free_block(bins是按照空間大小降序排列的,上層的bins大小要比下層的bins空間大),直到找到合適大小的一個。 如果最后沒有找到合適大小的,Query cache將啟動淘汰機制進行淘汰,以滿足空間申請的需求。 ### Query cache內存的回收 在需要申請內存塊時,如果沒有找到合適大小的free block, Query cache將啟動淘汰機制來淘汰最舊的緩存記錄,釋放的block將被分配到對于大小的bins中。如果分配過程中發現當前回收的free block和bins中free block地址相鄰, 當前回收的free block將會和相鄰的free block進行合并,重新插入到大小合適的bins中。另外Query cache通過flush query cache語句可以自動整理Query cache的defragments。 ## Query cache相關的幾個重點系統變量 #### query_cache_type | 范圍 | SESSION | |---|---|---| | 類型 | ENUM | |---|---|---| | 功能 | a) ON: cache所有SELECT語句。 b) OFF: 關閉query cache。(默認)。 c) DEMAND: 使用SQL_CACHE hint的SELECT語句才可以緩存 | #### query_cache_size | 范圍 | GLOBAL | |---|---|---| | 類型 | ULong | | 功能 | a) 設置Query cache的大小,設置范圍是(0 ~ ULONG_MAX)。 b) 默認值是1M。| #### query_cache_limit | 范圍 | GLOBAL | |---|---|---| | 類型 | ULong | | 功能 | a) 設置最大結果集大小范圍,如果結果集超出了該值的大小,將不會被緩存。 設置范圍是(0 ~ ULONG_MAX)。 b) 默認值是1M。| #### query_cache_min_res_unit | 范圍 | GLOBAL | |---|---|---| | 類型 | ULong | | 功能 | a) 設置內存申請的最小單元塊的大小,如果設置太大會影響Query Cache的實際使用率,造成空間浪費。 如果設置太小會增加內存的分配以及合并成本。設置范圍是(0 ~ ULONG_MAX)。 b) 默認值是4K。 | ### Query cache相關的兩個Hints #### sql_no_cache 功能: 當前sql語句忽略使用query cache. #### sql_cache 功能: 當query_cache_type為ON或者DEMAND時,考慮緩存當前sql語句的結果集。 ## Query cache的工作原理 為了快速查找,Query cache中維護著一個HASH map,用來記錄Query對應的其所在的query_cache_block。其對應的Key由query + database + flag(包含影響執行結果的所有環境變量)組成。如果當前Query與任何Key比較一致的話,對應的結果集就可以被直接返回。 ## Query cache 的失效 當一個表發生改變時,所有與該表相關的cached queries將失效。一個表發生變化,包含多種語句,比如 INSERT, UPDATE, DELETE, TRUNCATE TABLE,ALTER TABLE, DROP TABLE, 或者 DROP DATABASE。 為了加速失效過程,Query cache中維護著一個HASH map, 用來記錄table對應的query_cache_block_table。其Key由db_name + table_name構成。通過Key的比較可以獲取query_cache_block_table,該對象包含一個雙向鏈表,記錄了所有與該表相關的cached queries。通過這樣的方式便可以快速的失效一個表對應的所有cached queries。 ## Query cache 的監控 * Query cache 通過show status可以看到如下一系列的狀態信息: | Qcache_total_blocks | Query cache總的塊數。 | |--------|--------|--------| | Qcache_free_blocks | Query cache的free blocks數。 | | Qcache_hits | 通過Query cache,命中的query次數。 | | Qcache_inserts | 該變量記錄了之前有多少條query及其數據集成功插入了Query Cache中,即便插入的記錄后來被淘汰了,該值也不會受到影響。 | | Qcache_lowmem_prunes | Query cache中淘汰的query記錄數。 | | Qcache_not_cached | 未被緩存的query數。 | | Qcache_queries_in_cache | 當前Query cache存在的query記錄數,如果有記錄被淘汰了,該值就會發生變化。注意與Qcache_inserts的不同。 | | Qcache_total_blocks | 當前Query cache中總的blocks個數。 | * Optimizer_trace中會顯示“query_result_read_from_cache:true”這樣的信息。 ## 總結 如果當前用戶頻繁使用同樣的query進行查詢,Query cache對于性能的提升是顯而易見的。但是也有不太理想的情況,Query cache由于不僅依賴于執行的query,同時也依賴于當時的執行環境,比如SQL_MODE信息,字符集等,因此對于多用戶共享Query cache,很難做到完全的共享。 另外,對于失效方式,目前MySQL做的并不到位,只要是表或表中的數據發生了變化便會引發相關cached queries失效,而更理想的方式是只有影響當前cached queries的執行結果的表的變化才引發相關cached plan失效。比如如果UPDATE語句并未修改某個cached queries的執行記過,其實可以不用對其失效。 我們會在接下來的文章中繼續剖析Query cache的并發處理過程,敬請期待。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看