mysql性能測試-------重要!!!


我們在做性能測試的目的是什么,就是要測出一個系統的瓶頸在哪里,到底是哪里影響了我們系統的性能,找到問題,然后解決它。當然一個系統由很多東西一起組合到一起,應用程序、數據庫、服務器、中中間件等等很多東西。那我們測試的時候上面這些東西里面任何一個環節都可能會出問題,都可能會影響我們系統的性能。這篇博客主要講下mysql數據庫咱們在做性能測試的時候應該監控什么東西,又有哪些需要優化的地方。

哪些東西會影響mysql的性能?

1.硬件
2.系統配置
3.數據庫表結構
4.SQL以及索引

 

 

 

硬件

硬件就指的是數據庫服務器的配置,服務器說白了就是一台電腦而已,如果電腦的配置高,cpu處理能力強,內存大,硬盤是ssd的,那肯定性能好。當然這種方式成本也是最高的,要花錢的嘛。

系統配置

系統配置一個指的是操作系統的配置,有一些操作系統的配置會影響mysql的性能,現在咱們大多數服務器都是用的linux服務器,linux上面一切東西都是基於文件的,mysql數據里面的表、數據等等都是文件存在磁盤上的。

linux系統有一個系統配置是文件打開的數量,默認是1024,也就是最多只能打開1024個文件,那在數據庫里面表比較多、並發大的情況下,這1024就不夠用了,要想獲取數據就得打開文件,但是打開文件的數量最多就1024個,就會導致有一些數據獲取不到,就得等待別的文件關閉之后,才能打開。那就要修改系統的配置,在/etc/security/limits.conf文件里面可以修改最大打開文件的數量。

 

 

 

還有一些mysql配置參數會影響mysql的性能。

sleep超時時間

mysql的連接數是提前配置好的,如果程序里面代碼寫的不好,有一些數據庫操作沒有及時關閉數據庫,那這個鏈接就不會釋放,會一直占用鏈接,這樣子並發大的情況下,就會導致數據庫連接數不夠用了,就連接不上數據庫了。mysql默認8小時不操作數據庫才會自動關閉鏈接,所以這個sleep的超時時間會影響mysql的性能。

獨立表空間設置
表空間是什么呢,就是每個表存放數據的地方。
舉個例子,一個倉庫,你要往倉庫里面放東西的話,你來一些東西你就隨便扔到里面,這樣東西一多,你要找到一個東西就很難找了。那怎么辦呢,我在倉庫里面放幾個貨架,每個貨架放同一個種類的東西,這樣的話,找一個東西就很方便了。
表空間呢就和這個貨架差不多, 每個表我單獨管理的話,那找數據就比較方便了
 
mysql5.6.6之前默認是共享的表空間,mysql5.6.6之后默認是開啟了獨立表空間的。
那什么是共享表空間呢?
就是說這個空間是所有的表都共享的,所有的表的數據都存在一個地方的。
 
你想一下,所有的貨架都存在一個倉庫里面的話,快遞員去拿貨的時候,人一多,可能進出都要排隊,拿貨的時候就比較慢了。
所以說 共享表空間如果在數據量和並發量比較大的情況下,對IO的消耗是比較大的,影響性能。
 
共享表空間還有一個缺點就是不能自動收縮,自動收縮是什么意思呢,剛建表的時候,表里面數據很少,就1條數據,可能占用空間就幾kb,到后來數據多了,占用了10個G的空間,然后發現有一些數據都是垃圾數據, 刪了5個G,那這個時候表空間就不會自動減小了,它還是10個G,浪費空間。
 
而獨立表空間就是每個表的表空間都是獨享的,用倉庫這個例子就是每個貨架都單獨在一個房間里頭,這樣的話快遞員去拿哪個東西,直接去那個房間里就好了,不用都擠在一個倉庫里了。
而使用了獨立的表空間,每個表都有自己的表空間,刪了數據也會自動收縮,就不會有上面的問題了。

 

 

 

讀/寫進程數配置

在mysql5.5之后讀、寫的進程數是可以配置的。默認讀和寫的進程數都是4個

當然我們都知道,人多好干活嘛。進程多就是干活的人多,具體配置根據cpu的核數和業務邏輯來配置這兩個值。

假如cpu是32核的,那么就是同時可以有32個進程在運行,就可以把這兩個值給調大。

假如說是系統是一個內容類的網站,大多數操作都是讀操作,那么就可以把讀的進程數設置大一點,寫的進程數設置的小一點。

怎么修改呢,找到mysql的配置文件,在[mysqld]節點下加入下面參數的即可

 

 

 

緩存配置

在說緩存配置之前咱們先了解清楚,計算機在處理任務的時候是怎么處理的,先從磁盤上讀取數據,然后放到內存里面,cpu去內存里面拿數據,然后處理

在寫的時候正好相反,cpu處理完之后,把數據放到內存里面,內存再放到磁盤里

那從上面,我們發現,如果數據直接從內存里面拿的話,那速度就快很多了,我們看下面的圖,讀1M的數據,內存里面比從磁盤上快多少。

 

 

 

從上面這個圖我們發現從內存里面讀數據比從磁盤里面取數據快了N倍。

那到mysql里面,如果取數據的時候,mysql先把一些數據緩存到內存里面的話,取數據直接從內存里面取不就快很多了

咱們在說mysql緩存之前,先說下mysql在執行一條查詢語句的時候都做了什么。

 

 

 從上面的圖我們發現,mysql是有兩個地方檢查了內存的。如果內存里面找到我們想要的數據,那么就不去磁盤上查詢數據了。那么這兩個緩存都是什么,怎么配置呢。

qcache配置

緩存完整的SELECT語句和查詢結果,當查詢命中緩存,MySQL會立刻返回結果,跳過解析、優化和執行階段。
查詢緩存會跟蹤系統中的每張表,如果這些表發生變化,那么和這張表相關的所有查詢緩存全部失效。
在檢查查詢緩存的時候,MySQL不會對SQL進行任何處理,它精確的使用客戶端傳來的查詢(select),只要字符大小寫,或者注釋有一點點不同,查詢緩存就認為是不同的查詢。
任何一個包含不確定的函數(比如now(),current_date())的查詢不會被緩存。
MySQL查詢緩存可以改善性能,但是在使用的時候也有一些問題需要注意: 開啟查詢緩存對於讀寫都增加了額外的開銷。對於讀,在查詢開始前需要先檢查緩存;對於寫,在寫入后需要更新緩存。 一般情況這些開銷相對較小,所以查詢緩存一般還是有好處的。但也要根據業務特征權衡是否需要開啟查詢緩存。

 

怎么配置呢,找到mysql的配置文件,在[mysqld]節點下加入下面參數的即可

 

 

innodb_buffer_pool配置

mysql里面還有一個緩存配置就是innodb_buffer_pool的配置,innodb是現在mysql的默認存儲引擎,存儲引擎說白了就mysql存數據的時候到底是怎么存的。

就是一個倉庫里面怎么擺放貨物的。

buffer pool是innodb存儲引擎帶的一個緩存池,查詢數據的時候,它首先會從內存中查詢,如果內存中存在的話,直接返回,從而提高查詢響應時間。
innodb buffer pool和qcache的區別是:qcacche緩存的是sql語句對應的結果集,buffer pool中緩存的是表中的數據。buffer pool一般設置為服務器物理內存的70%。

怎么配置呢,找到mysql的配置文件,在[mysqld]節點下加入下面參數的即可

 

 

 

mysql架構上的優化

讀寫分離

多點寫入

數據庫表結構優化

當然系統在設計表結構的時候,一般都是架構師和一幫開發已經把表結構設計好了,咱們沒達到那個級別架構上的東西咱也不懂,就在設計表結構的時候需要注意的一些東西。

       1、使用可以存下你的數據的最小數據類型
       2、使用簡單的數據類型,int類型和varchar類型上,mysql處理int類型更簡單
       3、盡可能的使用not null定義字段,可以為空的字段加上默認值
            因為如果不限制not null的話,字段值是可以為空的,默認為空就是null,如果是not null的話字段值寫空的話,就要寫'',一個空的字符串。
            null它在mysql里面也是要占用空間的,也不能利用索引,而空的字符串在mysql是不占用空間的,也可以利用索引。
       4、時間類型的,用UNIX_TIMESTAMP,因為是int類型的

 

mysql索引優化

索引是什么呢,就和字典的目錄一樣。有目錄了,那咱們查數據就快了。

最適合建索引的列是出現在where子句后面的列。

唯一索引的效果最好,因為是唯一的。

利用最左前綴。

索引並不是越多越好。

mysql索引有4種類型

1、普通索引

最普通的索引,所有列都可以加

 create index index_name on table_name (col);

 

2、主鍵索引

建表的時候加的主鍵

3、組合索引

create index index_name on table_name (col,col2);

4、唯一索引

CREATE UNIQUE INDEX index_name
ON table_name (column_name);
 去除重復、冗余索引

因為每個開發的水平都不一樣,不可避免的的會出現一些重復索引的問題。那我們怎么來查找有一些冗余的索引呢。

就要借助percona-toolkit這個工具了,它里面有pt-duplicate-key-checker這個工具可以幫咱們找出來哪些表里面有冗余的索引,並給出修改索引的語句。

pt-duplicate-key-checker -uroot -pxxx -dxx#-u指的是用戶 -p是密碼 -d是數據庫

 

這個能幫咱們找出來重復的索引,那還有一些根本就沒有必要用的索引,雖然索引建立的並不是重復,但是實際上並沒用查詢語句用到它,怎么辦呢,percona-toolkit這個工具里還有一個工具是pt-index-usage,它可以讀取慢查詢日志,幫咱們找到那些沒用的索引。

set global slow_query_log=on;#打開慢查詢日志
set global long_query_time=1;#設置記錄查詢超過多長時間的sql
set global slow_query_log_file='/tmp/slow_query.log';#設置mysql慢查詢日志路徑,此路徑需要有寫權限
set global log_queries_not_using_indexes=ON; #設置沒有使用索引的sql記錄下來
 
 
SHOW VARIABLES LIKE '%slow%';#查看慢查詢配置

mysql記錄的日志里面,咱們看着比較不清晰,咱們使用pt-query-digest這個工具幫咱們解析慢查詢日志,它會把所有的sql的執行時間以及具體sql,執行了多少次都幫咱們統計出來。

下面是pt-query-digest的用法

pt-query-digest --filter='$event->{fingerprint} =~ m/^select/i' slow.log #查看包含select語句的慢查詢
pt-query-digest  --since=12h  slow.log #最近12小時的
pt-query-digest  --since '2017-12-01 09:30:00' --until '2017-12-02 10:00:00' --filter='$event->{fingerprint} =~ m/^select/i'  slow.log #指定時間段

如果想實時的獲取有沒有執行時間長的sql,用下面這個sql語句

select id,`user`,`host`,DB,command,`time`,state,info from information_schema.PROCESSLIST where TIME>=60;

 

explain

通過慢查詢日志我們可以找到有問題的sql語句,那我們怎么看這個sql哪有問題呢,就要使用explain了,只要在你要執行sql語句前面加上explain即可

all<index<range<ref<eq_ref<const,system sql執行type列里最差到最優

sql優化時候需要注意的

查詢條件使用索引列,排序使用索引列

避免select *,一般select * 都會造成全表掃描

盡量避免子查詢,MySQL 的子查詢執行計划一直存在較大的問題,雖然這個問題已經存在多年,但是到目前已經發布的所有穩定版本中都普遍存在,一直沒有太大改善。雖然官方也在很早就承認這一問題,並且承諾盡快解決,但是至少到目前為止我們還沒有看到哪一個版本較好的解決了這一問題。

事物

銀行存錢例子。

表級鎖、行級鎖。

SELECT * FROM information_schema.INNODB_TRX\G

mysql性能測試工具

mysqlslap是mysql自帶的一個性能測試工具。它可以模擬各種並發,以及使用哪種sql,生成多少數據,運行多久,產生報告。

常用的選項

--concurrency    並發數量,多個可以用逗號隔開
--engines       要測試的引擎,可以有多個,用分隔符隔開,如--engines=myisam,innodb
--auto-generate-sql        用系統自己生成的SQL腳本來測試
--auto-generate-sql-load-type    要測試的是讀還是寫還是兩者混合的(read,write,update,mixed)
--number-of-queries           總共要運行多少次查詢。每個客戶運行的查詢數量可以用查詢總數/並發數來計算
--debug-info               額外輸出CPU以及內存的相關信息
--number-int-cols             創建測試表的int型字段數量
--number-char-cols             創建測試表的chat型字段數量
--create-schema             測試的database
--query 自己的SQL           腳本執行測試
--only-print                 如果只想打印看看SQL語句是什么,可以用這個選項

下面是使用的例子

100並發,運行1000次,寫操作和讀操作都有,自動生成sql,int類型字段2個,char類型10個,
mysqlslap -h127.0.0.1 -uroot -p123456 --concurrency=100 --auto-generate-sql --auto-generate-sql-load-type=mixed --engine=innodb --auto-generate-sql-add-autoincrement --number-int-cols=2 --number-char-cols=10 --number-of-queries=10
 
100並發,運行5000次,besttest這個數據庫上執行sql
mysqlslap -h127.0.0.1 -uroot -p123456 --concurrency=100  --query='select * from stu;' -create-schema=besttest --engine=innodb --number-of-queries=5000 --debug-info
 
100並發,運行5000次,besttest這個數據庫上執行指定的sql文件
mysqlslap -h127.0.0.1 -uroot -p123456 --concurrency=100  --query=/tmp/besttest.sql -create-schema=besttest --engine=innodb --number-of-queries=5000 --debug-info

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM