?一 ?簡介
咱們先不說cpu的頻率,內存的大?。ㄟ@個和索引一樣重要,但不是本文討論的內容),硬盤的尋道時間。想起mysql的調優,最起碼的必須知道explain執行計劃,慢sql日志,老舊的profile命令,新的performance_schema性能視圖和information_schema中當前事務和內存占用信息的相關表,還有 show engine innodb status的診斷信息,以及某些metrix中的tps,qps,iops的指標。(相關推薦:《MySQL教程》)
以上是為調優準備的一些工具,而數據庫都會為高可用提供很多大大小小的功能,大的有:復制,組復制,分區,文件鏈接:即log日志與數據文件等可分別放置不同硬盤。小的有:計算列,為列計算hash,索引合并,索引下推,MRR,BKA,Loose Index 等算法,以及填充因子等。
當然,沒有視圖索引和分布式分區視圖,以及join僅僅只支持nested這是mysql的不足,而sql server join的算法支持三種,loop while hash,極大的改善join的速度。mysql自帶提升性能的功能并不多,其他的就是經驗之談,比如靜態表,不要在子查詢中使用函數,盡量將子查詢變為join查詢,非字符串和blob列永遠比其他的數字或者時間列要慢,join |order by|group一定不要讓其在硬盤生成臨時表,當然這個和內存有關,窄表和寬表設計等,當然最后還是取決你的業務類型。
優化入手有兩種方法,一種是運行時的,即在運行的服務器上優化,一種是開發過程中。而無論哪種,performance_schema都會需要。
二 performance_schema講解
性能視圖是每個數據庫中都會有的,sql server是dm_*開頭的一系列內存表。而mysql就是performance_schema庫中的各種表,先看入口的幾個表:
SELECT?*?FROM?setup_timers;?--?計時定義表 select?*?from?setup_actors;?--?那些用戶需要收集信息 select?*?from?Setup_objects;?--?那些對象需要收集信息,比如mysql表, select?*?from?setup_consumers;?--?那些儀器的分類需要收集 select?*?from?setup_instruments;?--?收集儀器,每一個功能點都會有儀器的事件,開始和結束,然后開啟那個儀器,就會收集那個儀器的數據
首先我們看開啟performance_schema的開關:
show?variables?like?'performance_schema'?--?這是一個read?only變量
如果為OFF,則需要在配置文件中開啟。
那么下面就一個一個介紹這幾個入口表。
1 ,setup_actors表
全部用戶都可收集。
2,Setup_objects
那些對象可以收集,是table還是trigger等。至于關閉兩個列控制,enabled和timed字段設置為No,這幾個表都是如此。
3 ?setup_consumers
事件的分類,stages是步驟,一個語句在服務器執行的過程步驟,結果和profile一樣,profile方式不推薦,因為后面會去掉。transaction是事務的事件收集等。
4?setup_instruments
這個就是主要的事件監控儀器,如下:
5 最后就是setup_timers,配合performance_timers定義那些儀器分類是的時間類型,如下:
CYCLE:cpu時鐘,TIMER_FREQUENCY是一秒有多少,TIMER_RESOLUTION是每次增加多少,最后是多久獲取一次這個時間。
三 利用performance_schema獲取priofile數據
開啟相關的instrument:
我們看上面 instrument分類表setup_consumers中的信息,關于stage的行都是NO,那么我們需要改為YES,同時一會需要拿statements監控表中的信息,所以也需要開啟statements:
UPDATE?setup_consumers?SET?ENABLED?=?'YES' ???????WHERE?NAME?LIKE?'%stage%'; UPDATE?setup_consumers?SET?ENABLED?=?'YES' WHERE?NAME?LIKE?'%statements%';
?然后把stage的instrument開啟
UPDATE?performance_schema.setup_instruments?SET?ENABLED?=?'YES',?TIMED?=?'YES' ???????WHERE?NAME?LIKE?'%stage/%';???--?開啟所有執行步驟的監控 UPDATE?performance_schema.setup_instruments?SET?ENABLED?=?'YES',?TIMED?=?'YES' WHERE?NAME?LIKE?'%statement/%';
執行依據sql
?select?*?from?quartz.TestOne
查詢這條語句的queryid:
SELECT?EVENT_ID,?TRUNCATE(TIMER_WAIT/1000000000000,6)?as?Duration,?SQL_TEXT ???????FROM?performance_schema.events_statements_history_long?WHERE?SQL_TEXT?like?'%quartz%';
那么id就是509
然后執行性能監控表:
SELECT event_name AS Stage, TRUNCATE(TIMER_WAIT/1000000000000,6) AS Duration FROM performance_schema.events_stages_history_long WHERE NESTING_EVENT_ID=509
?
內容和老版本的profile結果一樣。
主要看下stage/sql/Sending data這一行,這一行是主要io相關的事件,一般情況下,sql慢了,而這一行數值比較大,那肯定硬盤讀數據慢了或者有鎖沖突。
那么就是用error log,有死鎖,mysql會將死鎖信息打入error日志,show engine innodb status只是全局的一些信息,如果要想看詳細的再去監控對應的instrument。
而且目前mysql8多支持NOWAIT和skiplocked兩個語句,用法還是select.. from 表明 for update/for nowait等,非常靈活的解決了死鎖的處理方式,當然你也可以讓其事務隔離級別為臟讀級別,但是并不能解決更多的業務類型,設置死鎖超時也是一個可行的辦法。