效能測試之Mysql資料庫調優

2022-05-04 08:06:14 字數 4140 閱讀 5719

1、我們在監控圖表中關注的效能指標大概有這麼幾個:cpu、記憶體、連線數、io讀寫時間、io操作時間、慢查詢、系統平均負載以及memoryover

2、介紹下grafana模板中各效能指標的意思

這個是mysql資料庫的連線數

這個圖示表示了慢查詢

上圖就是mysql資料庫的快取區,展示了最大快取以及已使用快取等資料

3、效能分析

一般在產生mysql瓶頸的時候往往伴隨著的是cpu使用率急速上公升,需要top看一下是哪個執行緒佔據了大量的cpu資源,如果發現mysql程序占用較高,那麼基本可以判斷是mysql資料庫出現了問題。

接下來就是對問題具體的分析和定位。

對於資料庫的操作基本上就是大量的查詢,會導致資料庫出現效能問題。對有問題的場景使用jmeter模擬場景進行併發,並觀察grafana的圖表。

mysql的幾個問題基本上就是:1、快取區較小,大量查詢導致了快取區溢位,使用io進行讀寫,眾所周知,io的讀寫速度遠遠比記憶體讀寫速度要慢得多。

2、sql語句問題,導致mysql資料庫出現瓶頸的查詢語句型別很多,最後會給大家列舉一些。

那麼怎麼定位到這些問題呢?

(1)在負載測試中,通過grafana圖表觀察memory over這個圖表,如果發現占用基本佔滿所分配給mysql資料庫快取區的記憶體,然後io讀寫時間非常長,讀寫頻率非常高,那基本上是可以判斷是快取區較小導致的問題。(這個問題已經很少出現了)

(2)判斷慢查詢:在mysql資料庫的配置檔案中找到

log_output=file,table #二選 1 或者 2

個都選slow_query_log=on

slow_query_log_file = /tmp/mysql-slow.log long_query_time = 1 #設定如何判斷慢查詢,這邊設定超過1s就算慢查詢

#使用完記得關閉

重啟mysql資料庫

在grafana圖表中如果看到慢查詢的時間超過1s時,基本判斷為存在慢查詢。

登入資料庫執行命令

select * from mysql.slow_log;#檢視慢查詢表資料
執行完這條命令後,可以檢視到所有超過1s的查詢語句,這個時候複製這條語句到查詢輸入框中,選中右鍵點選解釋。

type列,連線型別。乙個好的sql語句至少要達到range級別。杜絕出現all級別

key列,使用到的索引名。如果沒有選擇索引,值是null。可以採取強制索引方式

key_len列,索引長度

rows列,掃瞄行數。該值是個預估值

extra列,詳細說明。注意常見的不太友好的值有:using filesort, using temporary

mysql對於in做了相應的優化,即將in中的常量全部儲存在乙個陣列裡面,而且這個陣列是排好序的。但是如果數值較多,產生的消耗也是比較大的。再例如:select id from t where num in(1,2,3) 對於連續的數值,能用 between 就不要用 in 了;再或者使用連線來替換。

select *增加很多不必要的消耗(cpu、io、記憶體、網路頻寬);增加了使用覆蓋索引的可能性;當表結構發生改變時,前斷也需要更新。所以要求直接在select後面接上欄位名。

這是為了使explain中type列達到const型別

or兩邊的字段中,如果有乙個不是索引字段,而其他條件也不是索引字段,會造成該查詢不走索引的情況。很多時候使用 union all 或者是union(必要的時候)的方式來代替「or」會得到更好的效果

select * from 表a where id in (select id from 表b)

上面sql語句相當於

select * from 表a where exists(select * from 表b where 表b.id=表a.id)

區分in和exists主要是造成了驅動順序的改變(這是效能變化的關鍵),如果是exists,那麼以外層表為驅動表,先被訪問,如果是in,那麼先執行子查詢。所以in適合於外表大而內錶小的情況;exists適合於外表小而內錶大的情況。

關於not in和not exists,推薦使用not exists,不僅僅是效率問題,not in可能存在邏輯問題。如何高效的寫出乙個替代not exists的sql語句?

原sql語句

select colname … from a表 where a.id not in (select b.id from b表)

高效的sql語句

select colname … from a表 left join b表 on where a.id = b.id where b.id is null

在一些使用者選擇頁面中,可能一些使用者選擇的時間範圍過大,造成查詢緩慢。主要的原因是掃瞄行數過多。這個時候可以通過程式,分段進行查詢,迴圈遍歷,將結果合併處理進行展示

對於null的判斷會導致引擎放棄使用索引而進行全表掃瞄。

例如like 「%name」或者like 「%name%」,這種查詢會導致索引失效而進行全表掃瞄。但是可以使用like 「name%」。

對於聯合索引來說,如果存在範圍查詢,比如between,>,《等條件時,會造成後面的索引字段失效。

type

訪問型別

all   掃瞄全表資料

index 遍歷索引

range 索引範圍查詢

index_subquery 在子查詢中使用 ref

unique_subquery 在子查詢中使用 eq_ref

ref_or_null 對null進行索引的優化的 ref

fulltext 使用全文索引

ref   使用非唯一索引查詢資料

eq_ref 在join查詢中使用primary keyorunique not null索引關聯。

const 使用主鍵或者唯一索引,且匹配的結果只有一條記錄。

system const 連線型別的特例,查詢的表為系統表。

效能從好到差依次為:

system,const,eq_ref,ref,fulltext,ref_or_null,unique_subquery,index_subquery,range,index_merge,index,all,除了all之外,其他的type都可以使用到索引,除了index_merge之外,其他的type只可以用到乙個索引。

possible_keys

可能使用的索引,注意不一定會使用。查詢涉及到的字段上若存在索引,則該索引將被列出來。當該列為 null時就要考慮當前的sql是否需要優化了。

key顯示mysql在查詢中實際使用的索引,若沒有使用索引,顯示為null。

tips:查詢中若使用了覆蓋索引(覆蓋索引:索引的資料覆蓋了需要查詢的所有資料),則該索引僅出現在key列表中

1、sql語句不要寫的太複雜。

乙個sql語句要盡量簡單,不要巢狀太多層。

2、使用like的時候要注意是否會導致全表掃

3、盡量避免使用!=或<>操作符

在where語句中使用!=或<>,引擎將放棄使用索引而進行全表掃瞄。

4、盡量避免使用 or 來連線條件

在 where 子句中使用 or 來連線條件,引擎將放棄使用索引而進行全表掃瞄。

5、盡量避免使用in和not in

在 where 子句中使用 in和not in,引擎將放棄使用索引而進行全表掃瞄。

6、盡量避免使用表示式、函式等操作作為查詢條件

7、盡量避免大事務操作,提高系統併發能力。

8、任何地方都不要使用 select * from t ,用具體的字段列表代替「*」,不要返回用不到的任何字段。

9、盡量使用數字型字段,若只含數值資訊的字段盡量不要設計為字元型,這會降低查詢和連線的效能,並會增加儲存開銷。

10、索引並不是越多越好,索引固然可以提高相應的 select 的效率,但同時也降低了 insert 及 update 的效率

11、並不是所有索引對查詢都有效,sql是根據表中資料來進行查詢優化的,當索引列有大量資料重複時,sql查詢可能不會去利用索引

剖析資料庫效能調優技術之索引調優

剖析資料庫效能調優技術之索引調優 2008 1 28 9 37 00 by iulu 一 概述 隨著資料庫在各個領域的使用不斷增長,越來越多的應用提出了高效能的要求。資料庫效能調優是知識密集型的學科,需要綜合考慮各種複雜的因素 資料庫緩衝區的大小 索引的建立 語句改寫等等。總之,資料庫效能調優的目的...

MySQL效能測試調優

作業系統 基本操作 檢視磁碟分割槽mount選項 mount 永久修改分割槽mount選項 系統重啟後生效 修改檔案 etc fstab 中對應分割槽的mount options列的值 sudo t ext4 o remount,noatime,errors remount or 檔案系統優化 ex...

mysql資料庫效能調優總結積累

mysql資料庫的調優大概可以分為四大塊 0 架構調優 根據業務 讀寫分庫分表 主從 讀寫分離 1 配置的調優 開啟快取查詢 設定快取大小 最大連線數設定 資料庫引擎配置 myisam 讀操作,查詢快 innodb 寫操作,主庫,支援事務,安全 引擎配置 日誌配置 2 表結構的調優 建立合適的索引 ...