MySQL 如何分析SQL的查詢效率

2021-10-06 04:26:56 字數 3547 閱讀 3347

最近在學習深入mysql,記錄一下學習歷程和一些問題。

在日常操作中,總會有一些查詢得比較慢的sql,但是造成查詢慢的原因有很多,那麼我們要怎麼樣才能準確的找到問題所在呢?

先建立一張表

drop table if exists index_test01;

create table `index_test01`(`

id`int(11) not null auto_increment,/*auto_increment表示自增*/

`a` int(11) ,

`b` int(11) ,

`c` int(11) ,

`d` int(11) ,

primary key (`id

`),/*主鍵*/

key `idx_a`

(`a`

),/*為a欄位建立索引*/

key `idx_b_c`

(`b`

,`c`

)/*為b,c欄位建立聯合索引*/);

drop procedure if exists insert_index_test01; /*如果儲存過程insert_index_test01存在就刪除它*/

delimiter $$ /*改變結束符 mysql的預設結束符為";"*/

create procedure insert_index_test01(

) /*建立儲存過程insert_index_test01*/

begin

declare i int;/*宣告變數i*/

set i=1;/*設定i的初始值為1*/

while

(i<100000)do /*迴圈10萬次*/

insert into index_test01(a,b,c,d) values(i,i,i,i)

; /*自定義sql 這裡是為index_test01新增10萬條資料*/

set i=i+1;

end while

;end $$

delimiter ;/*還原結束符*/

call insert_index_test01(

); /* 執行儲存過程insert_t9_1 */

想要看到明顯的差距的話需要加表的資料

反覆執行

建立完畢後 執行sql

insert into index_test01(a,b,c,d)

select a,b,c,d from index_test01;

比如我們想看看下面sql是否走了索引

select * from index_test01 where c=9000
只需要在sql前 加上explain

explain select * from index_test01 where c=9000
下面是對這些欄位的一些解釋

explain相關字段解釋列名

注釋id

查詢編號

select_type

查詢型別

table

涉及到的**

partitions

匹配的分割槽:查詢將匹配記錄所在的分割槽。僅當使用 partition 關鍵字時才顯示該列。對於非分割槽表,該值為 null。

type

本次查詢的表連線型別

possible_keys

可能選擇的索引

key實際選擇的索引

key_len

被選擇索引的長度

ref與索引比較的列

rows

預計需要掃瞄的行數,對 innodb 來說,這個值是估值,並不一定準確

filtered

涉及到按條件篩選的行的百分比**

extra

附加資訊

select_type常見引數

value

解釋******

簡單查詢 (不使用關聯查詢或子查詢)

primary

如果包含子查詢或者關聯查詢,則最外層的查詢部分標記為 primary

union

聯合查詢中第二個及後面的查詢

dependent union

滿足依賴外部的關聯查詢中第二個及以後的查詢

union result

聯合查詢的結果

subquery

子查詢中的第乙個查詢

dependent subquery

子查詢中的第乙個查詢,並且依賴外部查詢

derived

用到派生表的查詢

materialized

被物化的子查詢

uncacheable subquery

乙個子查詢的結果不能被快取,必須重新評估外層查詢的每一行

uncacheable union

關聯查詢第二個或後面的語句屬於不可快取的子查詢

type常見引數

value

解釋system

查詢物件表只有一行資料,且只能用於 myisam 和 memory 引擎的表,這是最好的情況

const

基於主鍵或唯一索引查詢,最多返回一條結果

eq_ref

表連線時基於主鍵或非 null 的唯一索引完成掃瞄

ref基於普通索引的等值查詢,或者表間等值連線

fulltext

全文檢索

ref_or_null

表連線型別是 ref,但進行掃瞄的索引列中可能包含 null 值

index_merge

利用多個索引

unique_subquery

子查詢中使用唯一索引

index_subquery

子查詢中使用普通索引

range

利用索引進行範圍查詢

index

全索引掃瞄

all全表掃瞄

extra常見引數

value

解釋using filesort

將用外部排序而不是索引排序,資料較小時從記憶體排序,否則需要在磁碟完成排序

using temporary

需要建立乙個臨時表來儲存結構,通常發生對沒有索引的列進行 group by 時

using index

使用覆蓋索引

using where

使用 where 語句來處理結果

impossible where

對 where 子句判斷的結果總是 false 而不能選擇任何資料

using join buffer (block nested loop)

關聯查詢中,被驅動表的關聯欄位沒索引

using index condition

先條件過濾索引,再查資料

select tables optimized away

使用某些聚合函式(比如 max、min)來訪問存在索引的某個欄位時

如有補充,歡迎指點。

如何分析mysql的查詢語句

這裡順便總結一下mysql的監控情況,linux的系統級別監控就不提了,因為mysql是io密集型應用,所以重點關注iowait,對於mysql本身,qps 每秒內查詢的次數 tps 每秒內提交的事務,可以理解為insert update update thread running 當前處於活動狀態...

如何分析mysql的查詢語句

這裡順便總結一下mysql的監控情況,linux的系統級別監控就不提了,因為mysql是io密集型應用,所以重點關注iowait,對於mysql本身,qps 每秒內查詢的次數 tps 每秒內提交的事務,可以理解為insert update update thread running 當前處於活動狀態...

SQL查詢分析

有二個表.表bom資料量非常大.現是400w左右.表二pnostatus資料不大.現只有50條左右.都是自增主鍵.表bom主鍵為idno,相關列有pno 這個每pno可能有3000多個相同的.ldate 為資料插入時自動取當取時間 表pnostatus有主建id,相關列有pno,updatetime...