mysql優化一之查詢優化

這一篇筆記的mysql優化是注重於查詢優化,根據mysql的執行狀況,判斷mysql何時須要優化,關於數據庫開始階段的數據庫邏輯、物理結構的設計結構優化不是本文重點,下次再談
查看mysql語句的執行狀況,判斷是否須要進行優化java

當感受操做數據庫查詢語句速度變慢,不符合生產效率要求時,可按照如下步驟進行查看
一、 慢查詢的開啓與捕獲,查看多是哪些SQL語句形成的查詢速度慢
二、 explain+SQL語句
三、 show profile分析SQL語句在服務器內執行細節和生命週期狀況
四、 經過以上三個步驟大體肯定問題SQL以後,可聯繫運維人員或者DBA進行數據庫服務器參數的調整優化

如下分別經過java程序員可分析的前三個方面來討論mysql語句的查詢優化mysql

1、慢查詢

慢查詢日誌是mysql的一個日誌記錄,能夠用來記錄mysql語句執行時間超過指定的long_query_time的SQL語句,long_query_time的默認值是10s
慢查詢日誌默認狀況下是不開啓的,由於將數據保存到日誌會對性能有必定影響,測試環境下可手動打開,但注意手動開啓以後只對本次啓動生效,mysql關閉以後重啓恢復默認狀態,要想持久生效要改變my.ini配置文件(Window系統下),其餘系統變量也如此程序員

可經過show varaibles like '%slow_query_log%'來查看日誌開啓狀況sql

能夠用set long_query_time = 3;語句來改變默認的閥值,而後咱們能夠用show varaiables like 'long_query_
time'來查看是否更改生效,若沒有生效,可嘗試重啓一下mysql客戶端便可數據庫

而後咱們如今來測試一下,由於咱們平時我的測試學習的數據庫及其簡單的SQL語句可能沒有形成很慢的查詢,咱們能夠採用 select sleep(time)來模擬測試
(這個函數相似於java線程中的sleep函數)服務器

執行該函數以前slow.log文件:
mysql優化

執行sleep(4)函數,由於要讓你設置的這個time大於記錄到日誌裏面的時間閥值
運維

可已看到這條慢查詢話費的具體時間是4.041230,也能夠看到是哪一個用戶在哪一個數據庫操做的哪條具體SQL語句,咱們開啓慢查詢日誌的目的就是找到這樣的形成查速度減慢的SQL語句,爲第二步的explain提供基礎函數

mysqldumpslow日誌分析工具

在實際的數據庫使用過程當中可能會有多條日誌記錄,數據複雜,人工分析費事費力,mysql提供了一個日誌分析工具mysqldumpslow
能夠根據你設定的參數查詢出知足條件的日誌記錄,方便查看工具

可用的參數有
-s, 是表示按照何種方式排序
    排序方式有
        c: 訪問計數
        l: 鎖定時間

        r: 返回記錄

        t: 查詢時間

        al:平均鎖定時間

        ar:平均返回記錄數

        at:平均查詢時間
-t, 是top n的意思,即爲返回前面多少條的數據;

-g, 後邊能夠寫一個正則匹配模式,大小寫不敏感的;

示例
獲得返回記錄集最多的10個SQL。

mysqldumpslow -s r -t 10 /database/mysql/mysql06_slow.log

獲得訪問次數最多的10個SQL

mysqldumpslow -s c -t 10 /database/mysql/mysql06_slow.log

獲得按照時間排序的前10條裏面含有左鏈接的查詢語句。

mysqldumpslow -s t -t 10 -g 「left join」 /database/mysql/mysql06_slow.log

另外建議在使用這些命令時結合 | 和more 使用 ,不然有可能出現刷屏的狀況。

mysqldumpslow -s r -t 20 /mysqldata/mysql/mysql06-slow.log | more

2、explain+SQL語句

執行這個語句可讓開發人員看到select語句執行的詳細信息,開發人員能夠將上一步慢查詢中捕獲的慢查詢SQL語句進行分析,判斷查詢效率低的可能緣由
能夠幫助選擇更好的索引和寫出優化的查詢語句

使用explain咱們能夠獲得如下信息
表的讀取順序
數據讀取操做的類型
哪些索引可使用
哪些索引實際被使用
表之間的引用
每張表有多少行被優化器掃描

示例

咱們來逐個分析各字段
id:select查詢的序列號,表明的是select執行的順序,主要有如下三種狀況

id相同時,則按照從上到下依次執行  


id不一樣時,id值越大優先級越高,越先被執行  


id有相同有不一樣,則相同的id爲一個組,不一樣組的id值按照規則二的優先級執行,同組id則按照規則一依次執行

select_type:select查詢的類型,有如下經常使用幾種

simple:表示該查詢沒有子查詢和UNION鏈接查詢  
primary:有子查詢時的最外層查詢  
subquery:有子查詢時的內層嵌套查詢  
derived:在from中包含的select就稱爲derived(衍生)  ,mysql會遞歸這些子查詢,把結果放在臨時表中  
union:union的第二個或者最後一個  
union result:union的結果

table:執行當前SQL語句用到的表

partitions:表明當前表所使用的分區

type:顯示使用了何種查詢,按照常見的幾種查詢最好到最壞排序爲system>const>eq_ref>ref>range>index>all

system,const:mysql可以對這部分進行查詢優化使可以將其轉換成一個常量(system只返回一行,const有多行),如某一行的主鍵放入WHERE子句裏的方式來選取此行的主鍵,MySQL就能將這個查詢轉換成一個常量。而後就能夠高效的將表從聯接執行中移除  
eq_ref:使用該索引查找,mysql知道最多返回一條數據,能夠在使用主鍵或者惟一性索引查找時用到  
ref:非惟一性索引的索引查找  
range:範圍掃描,例如帶有between或者>,<,in等  
index:掃描全部索引行  
all:掃描全部數據行

possible_keys/kesy:表明可能用到的索引和實際用到的索引

key_len:在索引中使用的字節數

ref:顯示了以前的表在key列記錄的索引中查找值所用的列或常量

rows:mysq估計的要找到知足條件的行所須要掃描的行數

filtered:給出了一個百分比的值,這個百分比的值和rows列的值一塊兒使用,能夠估計出那些將要和QEP中的前一個表進行鏈接的行的數目。前一個表就是指id列的值比當前表的id小的表

extra:給出一些額外但重要的信息,常見重要的信息有

using index:使用了覆蓋索引,以免掃描表(良好狀況)  
    using filesort:索引建立數據排序方式不知足要求,mysql在外部從新排序(嚴重,須要優化)  
    using temporary:mysql建立使用了臨時表來保存信息(嚴重,須要優化) 
    using where:使用了where  
    using join buffer:在獲取鏈接條件時沒有使用索引,而且須要鏈接緩衝區來存儲中間結果(須要增長索引進行優化)

這個裏面咱們須要重點關注的屬性是type,keys,row,extra來判斷是否爲一個良好的查詢
更多栗子及分析見下一篇文章索引詳解

3、show profile

show profile是mysql用來分析SQL查詢語句的資源使用狀況的工具

使用方法:

一、 由於mysql這個功能默認是關閉的,因此先查看一下並開啓



(與開啓慢查詢日誌相似,可能須要重啓mysql客戶端才能生效)

二、 咱們執行一些測試的SQL語句以後運行show profiles語句

三、 咱們能夠選擇指定項指定SQL語句來分析


通常咱們查看的屬性就是cpu和block io兩個模塊

注意:

若出現如下任意一個狀況,都表示這是一個糟糕的SQL語句,須要優化 一、 convering heap to MyIsam查詢結果過大,內存不夠,須要記錄到磁盤上 二、 creating tmp table建立臨時表儲存數據,用完以後刪除 三、 copying to tmp table on disk將臨時表中的數據儲存到磁盤上 四、 locked

相關文章
相關標籤/搜索