Mysql下優(yōu)化SQL的一般步驟

通過show status和應(yīng)用特點了解各種SQL的執(zhí)行頻率
通過SHOW STATUS可以提供服務(wù)器狀態(tài)信息,也可以使用mysqladmin extended-status命令獲得。SHOW STATUS可以根據(jù)需要顯示session級別的統(tǒng)計結(jié)果和global級別的統(tǒng)計結(jié)果。
以下幾個參數(shù)對Myisam和Innodb存儲引擎都計數(shù):Com_select 執(zhí)行select操作的次數(shù),一次查詢只累加1;
Com_insert 執(zhí)行insert操作的次數(shù),對于批量插入的insert操作,只累加一次;
Com_update 執(zhí)行update操作的次數(shù);
Com_delete 執(zhí)行delete操作的次數(shù)。

以下幾個參數(shù)是針對Innodb存儲引擎計數(shù)的,累加的算法也略有不同:Innodb_rows_read select查詢返回的行數(shù);
Innodb_rows_inserted執(zhí)行Insert操作插入的行數(shù);
Innodb_rows_updated 執(zhí)行update操作更新的行數(shù);
Innodb_rows_deleted 執(zhí)行delete操作刪除的行數(shù)。

通過以上幾個參數(shù),可以很容易的了解當(dāng)前數(shù)據(jù)庫的應(yīng)用是以插入更新為主還是以查詢操作為主,以及各種類型的SQL大致的執(zhí)行比例是多少。對于更新操作的計數(shù),是對執(zhí)行次數(shù)的計數(shù),不論提交還是回滾都會累加。對于事務(wù)型的應(yīng)用,通過Com_commit和Com_rollback可以了解事務(wù)提交和回滾的情況,對于回滾操作非常頻繁的數(shù)據(jù)庫,可能意味著應(yīng)用編寫存在問題。此外,以下幾個參數(shù)便于我們了解數(shù)據(jù)庫的基本情況:Connections 試圖連接Mysql服務(wù)器的次數(shù)
Uptime  服務(wù)器工作時間
Slow_queries 慢查詢的次數(shù)

定位執(zhí)行效率較低的SQL語句
可以通過以下兩種方式定位執(zhí)行效率較低的SQL語句:可以通過慢查詢?nèi)罩径ㄎ荒切﹫?zhí)行效率較低的sql語句,用--log-slow-queries[=file_name]選項啟動時,mysqld寫一個包含所有執(zhí)行時間超過long_query_time秒的SQL語句的日志文件。可以鏈接到管理維護(hù)中的相關(guān)章節(jié)。
慢查詢?nèi)罩驹诓樵兘Y(jié)束以后才紀(jì)錄,所以在應(yīng)用反映執(zhí)行效率出現(xiàn)問題的時候查詢慢查詢?nèi)罩静⒉荒芏ㄎ粏栴},可以使用show processlist命令查看當(dāng)前MySQL在進(jìn)行的線程,包括線程的狀態(tài),是否鎖表等等,可以實時的查看SQL執(zhí)行情況,同時對一些鎖表操作進(jìn)行優(yōu)化。

通過EXPLAIN分析低效SQL的執(zhí)行計劃
通過以上步驟查詢到效率低的SQL后,我們可以通過explain或者desc 獲取MySQL如何執(zhí)行SELECT語句的信息,包括select語句執(zhí)行過程表如何連接和連接的次序。explain可以知道什么時候必須為表加入索引以得到一個使用索引來尋找記錄的更快的SELECT。 mysql> explain select sum(moneys) from sales a,companys b where a.company_id = b.id and a.year = 2006;+----------------+----------+-----------+----------------+----------------+----------+-----------+----------------+| select_type | table | type | possible_keys| key | key_len | rows | Extra |+----------------+----------+-----------+----------------+----------------+----------+-----------+----------------+| SIMPLE | b | index | PRIMARY | PRIMARY | 4 | 1 | Using index || SIMPLE | a | ALL | NULL | NULL | NULL | 12 | Using where |+----------------+----------+-----------+----------------+----------------+----------+-----------+----------------+2 rows in set (0.02 sec)說明:select_type:select 類型
table:輸出結(jié)果集的表
type:表示表的連接類型①當(dāng)表中僅有一行是type的值為system是最佳的連接類型;
②當(dāng)select操作中使用索引進(jìn)行表連接時type的值為ref;
③當(dāng)select的表連接沒有使用索引時,經(jīng)常會看到type的值為ALL,表示對該表進(jìn)行了全表掃描,這時需要考慮通過創(chuàng)建索引來提高表連接的效率。

possible_keys:表示查詢時,可以使用的索引列.
key:表示使用的索引
key_len:索引長度
rows:掃描范圍
Extra:執(zhí)行情況的說明和描述

確定問題,并采取相應(yīng)的優(yōu)化措施
經(jīng)過以上步驟,基本可以確認(rèn)問題出現(xiàn)的原因,可以根據(jù)情況采取相應(yīng)的措施,進(jìn)行優(yōu)化提高執(zhí)行的效率。例如上面的例子,我們確認(rèn)是對a表的全表掃描導(dǎo)致效率的不理想,我們對a表的year字段創(chuàng)建了索引,查詢需要掃描的行數(shù)明顯較少。 mysql> explain select sum(moneys) from sales a,companys b where a.company_id = b.id and a.year = 2006;+----------------+----------+-----------+----------------+----------------+----------+-----------+----------------+| select_type | table | type | possible_keys| key | key_len | rows | Extra |+----------------+----------+-----------+----------------+----------------+----------+-----------+----------------+| SIMPLE | b | index | PRIMARY | PRIMARY | 4 | 1 | Using index || SIMPLE | a | ref | year | year | 4 | 3 | Using where |+----------------+----------+-----------+----------------+----------------+----------+-----------+----------------+2 rows in set (0.02 sec)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容