1. 程式人生 > >使用 EXPLAIN 關鍵字 檢查SQL語句效率

使用 EXPLAIN 關鍵字 檢查SQL語句效率

explain詳細說明

通過explain可以知道mysql是如何處理語句,分析出查詢或是表結構的效能瓶頸。通過expalin可以得到:

1. 表的讀取順序
2.表的讀取操作的操作型別
3.哪些索引可以使用
4. 哪些索引被實際使用
5.表之間的引用
6.每張表有多少行被優化器查詢

explain顯示欄位 fff

1. id :語句的執行順序標識

2. select_type:使用的查詢型別,主要有以下幾種查詢型別:

1).simple 簡單型別

語句中沒有子查詢或union

f2

2). primary 最外層的select ,不是主鍵

f3

3).  union

union是在select 語句中第二個select語句後面所有的select,第一個select 為primary

4).dependent subquery

子查詢中內層中第一個select語句

f4

5).  dependent  union

子查詢中union且為union中第二個select開始的後面所有select,依賴於外部的結果集。

f5

6). SUBQUERY
f6

7).devived

派生表的查詢語句

f7

8). uncacheable subquery

結果集無法快取的子查詢

9). union result

union中合併的結果

f9

3. table 

顯示這一步所訪問的資料庫中表的名稱

4. type 

這列很重要,顯示了連線使用了哪種類別,有無使用索引。type代表查詢執行計劃(QEP)中指定的表使用的連線方式。從最好到最差的連線型別為 1.system、2.const、3. eq_reg、4. ref、5. range、6.index、7. all

1). system
system為const一個特例,即表中只有一條記錄。
2). const
const是在where條件以常量作為查詢條件,表中最多有一條記錄匹配。由於是常量,所以實際上只需要讀一次。

g1

3). eq_reg
最多隻會有一條匹配結果,一般是通過主鍵或是唯一索引來訪問。一般會出現在連線查詢的語句中。

g2

4). ref
join 語句中被驅動的表索引引用查詢。這個值表示所有具有匹配的索引值的行都被用到。

5).range
索引範圍掃描

6). index

全索引樹被掃描

7). all
全表掃描,效果是最不理想的。

5. possible_keys
查詢可以利用的索引,如果沒有任何索引可以使用,就會顯示成null,這項對內容的優化時索引的調整非常重要。

6.key

從possible_keys中所選擇使用的索引

7. key_len

key_len列顯示mysql決定使用的鍵長度,如果鍵是null,則長度為null。使用的索引長度,一般越短越好。

8. ref 
列出的是通過常量const,或是某個表的某個欄位來過濾的。

9.rows
通過系統收集到的統計資訊,估計出來的結果集記錄條數

10. extra

Extra:查詢中每一步實現的額外細節資訊,主要可能會是以下內容:

1). Distinct:查詢distinct值,所以當mysql找到了第一條匹配的結果後,將停止該值的查詢而轉為後面其他值的查詢; FullscanonNULLkey:子查

詢中的一種優化方式,主要在遇到無法通過索引訪問null值的使用使用;

2).  ImpossibleWHEREnoticedafterreadingconsttables:MySQLQueryOptimizer通過收集到的統計資訊判斷出不可能存在結果;

3). Notables:Query語句中使用FROMDUAL或者不包含任何FROM子句;

4). Notexists:在某些左連線中MySQLQueryOptimizer所通過改變原有Query的組成而使用的優化方法,可以部分減少資料訪問次數;

5). Rangecheckedforeachrecord(indexmap:N):通過MySQL官方手冊的描述,當MySQLQueryOptimizer沒有發現好的可以使用的索引的時候,如果發現如果來自前面的表的列值已知,可能部分索引可以使用。對前面的表的每個行組合,MySQL檢查是否可以使用range或index_merge訪問方法來索取行。

6). Selecttablesoptimized away:當我們使用某些聚合函式來訪問存在索引的某個欄位的時候,MySQLQueryOptimizer會通過索引而直接一次定位到所需的資料行完成整個查詢。當然,前提是在Query中不能有GROUPBY操作。如使用MIN()或者MAX()的時候;

7). Usingfilesort:當我們的Query中包含ORDERBY操作,而且無法利用索引完成排序操作的時候,MySQLQueryOptimizer不得不選擇相應的排序演算法來實現。

8).  Usingindex:所需要的資料只需要在Index即可全部獲得而不需要再到表中取資料;

9). Usingindexforgroup-by:資料訪問和Usingindex一樣,所需資料只需要讀取索引即可,而當Query中使用了GROUPBY或者DISTINCT子句的時候,如果分組欄位也在索引中,Extra中的資訊就會是Usingindexforgroup-by;

10). Usingtemporary:當MySQL在某些操作中必須使用臨時表的時候,在Extra資訊中就會出現Usingtemporary。主要常見於GROUPBY和ORDERBY等操作中。

11). Usingwhere:如果我們不是讀取表的所有資料,或者不是僅僅通過索引就可以獲取所有需要的資料,則會出現Usingwhere資訊;

12). Usingwherewithpushedcondition:這是一個僅僅在NDBCluster儲存引擎中才會出現的資訊,而且還需要通過開啟ConditionPushdown優化功能才可能會被使用。控制引數為engine_condition_pushdown。

CREATE TABLE `item` (
  `i_id` int(11) NOT NULL,
  `i_im_id` int(11) DEFAULT NULL,
  `i_name` varchar(24) DEFAULT NULL,
  `i_price` decimal(5,2) DEFAULT NULL,
  `i_data` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`i_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;

CREATE TABLE `orders` (
  `o_id` int(11) NOT NULL,
  `o_d_id` tinyint(4) NOT NULL,
  `o_w_id` smallint(6) NOT NULL,
  `o_c_id` int(11) DEFAULT NULL,
  `o_entry_d` datetime DEFAULT NULL,
  `o_carrier_id` tinyint(4) DEFAULT NULL,
  `o_ol_cnt` tinyint(4) DEFAULT NULL,
  `o_all_local` tinyint(4) DEFAULT NULL,
  PRIMARY KEY (`o_w_id`,`o_d_id`,`o_id`),
  KEY `idx_orders` (`o_w_id`,`o_d_id`,`o_c_id`,`o_id`),
  CONSTRAINT `fkey_orders_1` FOREIGN KEY (`o_w_id`, `o_d_id`, `o_c_id`) REFERENCES `customer` (`c_w_id`, `c_d_id`, `c_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;