一般使用sql的時候你是不會去想到優化。但是面對乙個有sql效能問題的資料庫時,我們應該如何入手進行系統的分析,使得能夠盡快定位問題sql,並且盡快解決問題。
1.使用show status 命令了解各種sql的執行頻率
引用例如在mysql的cline上輸入
show status like 'com_%';
顯示的是一些:com_***.
引用com_select:執行select操作的次數
com_insert:執行insert操作的次數,對於批量插入的insert操作,只累加一次
com_update:執行update操作的次數
com_delete:執行delete操作的次數
上面這些引數對於所有儲存引擎的表操作都會進行累加。下面有些引數只針對innodb儲存引擎的,累加的演算法也有點不一樣。
引用innodb_rows_read:select查詢返回的行數
innodb_rows_inserted:執行insert操作插入的行數
innodb_rows_updated:執行update操作更新的行數
innodb_rows_deleted:執行delete操作刪除的行數
通過上面的一些引數,我們可以了解當前資料庫的應用是以插入為主還是以查詢為主。以及各種型別的sql大致的執行比例是多少。對於更新操作的計數,是對執行次數的計數,不管提交還是回滾都會進行累加。
對於事務型的應用,通過com_commit和com_rollback進行分析。如果回滾操作非常頻繁那麼要思考下是不是編寫存在問題。
下面有幾個引數用於了解資料庫的基本情況
引用connections:試圖連線mysql伺服器的次數(執行的命令是:show status like 'con_%';)
uptime: 伺服器工作時間(執行的命令是:show status like 'up_%';)
slow_queries:慢查詢的次數(執行的命令是:show status like 'slow_%';)
2. 定位執行效率較低的sql語句
要想定義效率較低的sql可以按照下面兩種方式試試。
引用1. 通過慢查詢日誌定位那些執行效率較低的sql語句,用 --log-slow-queries[=file_name]選項啟動時,mysqld寫乙個包含所有執行時間超過long_query_time秒的sql語句的日誌檔案。
2. 慢查詢日誌在查詢結束以後才記錄,所以在應用反映執行效率出現問題的時候進行查詢慢查詢日誌並不能定位問題,可以使show processlist 命令檢視當前mysql在進行的執行緒,包括執行緒的狀態,是否鎖表等,可以實時地檢視sql的執**況,同時對一些鎖表操作進優化。
3. 使用explain分析低效sql的執行計畫。
在查詢到效率低的sql語句後,那我們可以使用explain或者desc命令獲取myswl如何執行select語句的資訊,包括在select語句執行過程中表如何連線和連線的順序。
例如你想計數***x年公司的銷售額,那麼需要操作sales和comapny table,並對money欄位進行sum操作。看看怎麼使用explain:
引用explain select sum(moneys) from sales a company b where a.company_id = b.id and a.year=***x \g;(注意加上\g是為了更好的看)
顯示如下:
*********************** 1. row***************************
id: 1
select_type: ******
table: a
type: all
possible_keys: null
key:null
key_len: null
ref: null
rows:1000
extra: using where
*********************** 2. row***************************
id: 2
select_type: ******
table: b
type: ref
possible_keys: ind_company_id
key:ind_comapany_id
key_len: 5
ref: sakila.a.company_id
rows:1
extra: using where;using index
下面解釋下每個列的含義:
引用select_type: 表示select的型別,常見的取值為******(簡單表,不使用表連線或者子查詢)、primary(主查詢,即外層的查詢)、union、subquery
table: 輸出結果集的表
type: 表示表的連線型別,效能由好到差的型別型別為
(system(表中僅有一行,即常量表),
const(單錶中最多有乙個匹配行),
eq_ref(對於前面的每一行,在此表中只查詢一條記錄),
ref(使用普通的索引),
ref_or_null(和ref類似,但是條件中包含對於null查詢),
index_merge(索引合併優化),
unique_subquery(in的後面是乙個查詢主鍵欄位的子查詢),
index_subquery(類似unique_subquery,主要是in的後面是查詢非唯一索引欄位的子查詢),
range(單錶中的範圍查詢),
index(對於當前的每一行,都通過查詢索引來得到資料),
all(對於當前的每一行,都通過全表掃瞄來得到資料))
possible_keys: 表示查詢時,可能使用的索引
key:表示實際使用的索引
key_len:索引欄位的長度
rows:掃瞄行的數量
extra:執**況的說明和描述
通過上面的思路進行分析和定位sql語句有可能出現的低效率的情況。並且進行解決。下篇我講敘述關於sql優化之索引的問題。
SQL優化的筆記
一般使用sql的時候你是不會去想到優化。但是面對乙個有sql效能問題的資料庫時,我們應該如何入手進行系統的分析,使得能夠盡快定位問題sql,並且盡快解決問題。1.使用show status 命令了解各種sql的執行頻率 quote 例如在mysql的cline上輸入 show status like...
sql優化筆記
一 資料庫內連線原理 在sql server中,我們所常見的表與表之間的inner join,outer join都會被執行引擎根據所選的列,資料上是否有索引,所選資料的選擇性轉化為loop join,merge join,hash join這三種物理連線中的一種。1.oracle的表連線hash ...
sql 優化筆記
mysql 原文 原文這裡的引數為list,這裡我用的,分割的字串 思路就是將in中的資料處理成乙個表,進行表的關聯查詢 替換掉in select fm.id,fm.configuration id,fm.name code,fm.manufactor code,fm.type,fm.is sign...