MySQL資料庫效能優化之一(快取引數優化)

2021-08-14 01:53:34 字數 3354 閱讀 4503

資料庫屬於io密集型的應用程式,其主要職責就是資料的管理及儲存工作。而我們知道,從記憶體中讀取乙個資料庫的時間是微秒級別,而從一塊普通硬碟上讀取乙個io是在毫秒級別,二者相差3個數量級。所以,要優化資料庫,首先第一步需要優化的就是 io,盡可能將磁碟io轉化為記憶體io。本文先從 mysql 資料庫io相關引數(快取引數)的角度來看看可以通過哪些引數進行io優化:

query_cache_size/query_cache_type (global)

query cache 作用於整個 mysql instance,主要用來快取 mysql 中的 resultset,也就是一條sql語句執行的結果集,所以僅僅只能針對select語句。當我們開啟了 query cache 功能,mysql在接受到一條select語句的請求後,如果該語句滿足query cache的要求(未顯式說明不允許使用query cache,或者已經顯式申明需要使用query cache),mysql 會直接根據預先設定好的hash演算法將接受到的select語句以字串方式進行hash,然後到query cache 中直接查詢是否已經快取。也就是說,如果已經在快取中,該select請求就會直接將資料返回,從而省略了後面所有的步驟(如 sql語句的解析,優化器優化以及向儲存引擎請求資料等),極大的提高效能。

當然,query cache 也有乙個致命的缺陷,那就是當某個表的資料有任何任何變化,都會導致所有引用了該錶的select語句在query cache 中的快取資料失效。所以,當我們的資料變化非常頻繁的情況下,使用query cache 可能會得不償失。

query cache的使用需要多個引數配合,其中最為關鍵的是 query_cache_size 和 query_cache_type ,前者設定用於快取 resultset 的記憶體大小,後者設定在何場景下使用 query cache。在以往的經驗來看,如果不是用來快取基本不變的資料的mysql資料庫,query_cache_size 一般 256mb 是乙個比較合適的大小。當然,這可以通過計算query cache的命中率(qcache_hits/(qcache_hits+qcache_inserts)*

100))來進行調整。query_cache_type可以設定為0(off),1(on)或者2(demond),分別表示完全不使用query cache,除顯式要求不使用query cache(使用sql_no_cache)之外的所有的select都使用query cache,只有顯示要求才使用query cache(使用sql_cache)。

binlog_cache_size (global)

binlog cache 用於在開啟了二進位制日誌(binlog)記錄功能的環境,是 mysql 用來提高binlog的記錄效率而設計的乙個用於短時間內臨時快取binlog資料的記憶體區域。

一般來說,如果我們的資料庫中沒有什麼大事務,寫入也不是特別頻繁,2mb~4mb是乙個合適的選擇。但是如果我們的資料庫大事務較多,寫入量比較大,可與適當調高binlog_cache_size。同時,我們可以通過binlog_cache_use 以及 binlog_cache_disk_use來分析設定的binlog_cache_size是否足夠,是否有大量的binlog_cache由於記憶體大小不夠而使用臨時檔案(binlog_cache_disk_use)來快取了。

key_buffer_size (global)

key buffer 可能是大家最為熟悉的乙個 mysql 快取引數了,尤其是在 mysql 沒有更換預設儲存引擎的時候,很多朋友可能會發現,預設的 mysql 配置檔案中設定最大的乙個記憶體引數就是這個引數了。key_buffer_size 引數用來設定用於快取 myisam儲存引擎中索引檔案的記憶體區域大小。如果我們有足夠的記憶體,這個快取區域最好是能夠存放下我們所有的 myisam 引擎表的所有索引,以盡可能提高效能。

此外,當我們在使用myisam 儲存的時候有乙個及其重要的點需要注意,由於 myisam 引擎的特性限制了他僅僅只會快取索引塊到記憶體中,而不會快取表資料庫塊。所以,我們的 sql 一定要盡可能讓過濾條件都在索引中,以便讓快取幫助我們提高查詢效率。

bulk_insert_buffer_size (thread)

和key_buffer_size一樣,這個引數同樣也僅作用於使用 myisam儲存引擎,用來快取批量插入資料的時候臨時快取寫入資料。當我們使用如下幾種資料寫入語句的時候,會使用這個記憶體區域來快取批量結構的資料以幫助批量寫入資料檔案:

insert … select …

insert … values (…) ,(…),(…)…

load data infile… into… (非空表)

innodb_buffer_pool_size(global)

當我們使用innodb儲存引擎的時候,innodb_buffer_pool_size 引數可能是影響我們效能的最為關鍵的乙個引數了,他用來設定用於快取 innodb 索引及資料塊的記憶體區域大小,類似於 myisam 儲存引擎的 key_buffer_size 引數,當然,可能更像是 oracle 的 db_cache_size。簡單來說,當我們操作乙個 innodb 表的時候,返回的所有資料或者去資料過程中用到的任何乙個索引塊,都會在這個記憶體區域中走一遭。

和key_buffer_size 對於 myisam 引擎一樣,innodb_buffer_pool_size 設定了 innodb 儲存引擎需求最大的一塊記憶體區域的大小,直接關係到 innodb儲存引擎的效能,所以如果我們有足夠的記憶體,盡可將該引數設定到足夠打,將盡可能多的 innodb 的索引及資料都放入到該快取區域中,直至全部。

我們可以通過 (innodb_buffer_pool_read_requests – innodb_buffer_pool_reads) / innodb_buffer_pool_read_requests * 100% 計算快取命中率,並根據命中率來調整 innodb_buffer_pool_size 引數大小進行優化。

innodb_additional_mem_pool_size(global)

這個引數我們平時調整的可能不是太多,很多人都使用了預設值,可能很多人都不是太熟悉這個引數的作用。innodb_additional_mem_pool_size 設定了innodb儲存引擎用來存放資料字典資訊以及一些內部資料結構的記憶體空間大小,所以當我們乙個mysql instance中的資料庫物件非常多的時候,是需要適當調整該引數的大小以確保所有資料都能存放在記憶體中提高訪問效率的。

這個引數大小是否足夠還是比較容易知道的,因為當過小的時候,mysql 會記錄 warning 資訊到資料庫的 error

log 中,這時候你就知道該調整這個引數大小了。

效能優化 MySQL資料庫優化

可以從哪幾個方面進行資料庫的優化?如下圖所示 a sql及索引優化 根據需求寫出良好的sql,並建立有效的索引,實現某一種需求可以多種寫法,這時候我們就要選擇一種效率最高的寫法。這個時候就要了解sql優化 b 資料庫表結構優化 根據資料庫的正規化,設計表結構,表結構設計的好直接關係到寫sql語句。c...

資料庫效能優化 MySQL

序 即使有較長的快取有效期和較理想的快取命中率,但是快取的建立和快取過期後的重建都是需要訪問資料庫的。對資料庫寫操作不是很容易引入快取策略。11.1 檢視資料庫狀態 可以通過show status show innodb status 來檢視mysql資料庫的狀態,使用mysqlreport這個第三...

效能優化 mysql資料庫

一 mysql常用命令 1.開啟日誌 1 show global variables like genera 2 set global general log on 3 set global general log off 2.mysql如果開了set autocommit 0,那麼所有的語句一定是...