MySQL SQL語句優化explain關鍵字

概述

在目前這個大數據,大流量時代,我們的網站不光流量大,數據量也會非常的巨大。在巨大的數據量中精確找出我們需要的數據,這個對我們數據庫壓力比較大。而我們在不考慮進行分庫分表的操作時,進行SQL語句優化是一個很好的解決辦法,下面介紹explain關鍵詞分析SQL語句,及使用索引進行優化查詢。

explain關鍵字使用

explain使用格式

	EXPLAIN SELECT
	*
	FROM
		SCORE
	WHERE
		CNO = '3-105'
	AND DEGREE > (
		SELECT
			DEGREE
		FROM
			SCORE
		WHERE
			SNO = 109
	)

查詢結果

id select_type table type possible_keys key key_len ref rows extra
1 PRIMARY SCORE ALL null null null null 12 Using where
2 SUBQUERY SCORE ALL null null null null 12 Using where

explain表格各個屬性分析

  • id:select查詢的序列號,包含一組數字,表示查詢中執行select子句或操作表的順序
  1. id相同時,執行順序由上至下
  2. id不同時,如果是子查詢,序號id會遞增,id值越大優先級越高,越先被執行,在所有組中,id值越大優先級越高
  • select_type:查詢類別,主要是區別普通查詢,聯合查詢,子查詢等複雜查詢
  1. simple簡單查詢,不包含子查詢
  2. primary:包含子查詢,爲最外層查詢
  3. subquery:子查詢
  4. derived:衍生表,虛擬表
  5. union:出現union關鍵字
  6. union select:在union結果中查詢
  • table:查詢的表名
  • type:執行計劃包含的信息,顯示查詢使用了何種類型
type類型從最好到最差

system > const > eq_ref > ref > range >index > all
  1. system:表中只有一條記錄(等於系統表),這是const類型的特例,平時不會出現,這個可以忽略不計。
  2. const:表示通過索引一次就找到了,const用於比較primary key或者union索引,因爲只匹配一行數據,所以很快,如將主鍵置於where中。
  3. eq_ref:唯一性索引掃描,對於每個索引鍵,表中只有一條記錄與之匹配。常見主鍵或者唯一索引掃描
  4. ref:非唯一索引掃描,返回匹配條件的所有行。本質上也是一種索引,他返回所有匹配某個單獨值得所有行,然而,他可能會找到多個符合條件得行,所以他應該屬於查找和掃描得混合體。
  5. range:只檢索給定範圍的行,使用索引來選擇行。key列顯示使用了哪些索引,一般就在你的where語句中出現了between、<、>、in等查詢,這種範圍掃描比全表掃描要好,因爲它只需要開始於索引的某一個點,而結束於某一個點,不用全表掃描。
  6. index:full index scan,indexall的區別爲index類型只遍歷索引樹。這通常比all快,因爲索引文件通常比數據文件小(也就是說雖然allindex都是全表掃描,但是index是從索引文件中進行掃描,all是通過硬盤中讀取的)
  7. all:全表掃描
  • possible_keys:顯示可能應用於查詢的索引,一個或者多個。查詢涉及到字段存在索引,則將索引列出,但不一定在查詢中使用。
  • key:實際查詢使用的索引。如果爲null,則沒有用到索引,若使用到了覆蓋索引,則該索引只出現在key列表中。
  • key_len:顯示索引中使用的字節數,可通過該列計算查詢中使用到索引長度。在不損失精度下,長度越短越好。key_len顯示的值爲索引字段的最大長度,並非實際使用長度,即key_len是根據表定義計算而得,不是通過表內檢索出得。
  • ref:顯示索引的哪一列被使用了,如果可能的話,是一個常數。哪些列或者常量被用於查找索引列上值。
  • rows:根據表統計信息及索引選用情況,大致估算出找到所需的記錄需要讀取的行數
  • extra:不適合在其他列中顯示,但又十分重要的信息
  1. using filesort:說明MySQL會對數據使用一個外部的索引排序,而不是按照表內索引進行讀取。MySQL中無法利用索引完成排序操作稱之爲文件排序。如果出現這種情況,查詢將會非常的慢
  2. using temporary:說明使用臨時表保存中間結果,MySQL在對查詢結果進行排序時,使用臨時表。常見於排序order bygroup by。出現這種情況查詢會非常慢。
  3. using index:表示相應的select操作中使用覆蓋索引(covering index),避免訪問數據行,效率很好!如果同時出現using where,表明索引被用來執行索引值查找;如果沒有同時出現using where,表明索引用來讀取非執行查找動作。
  4. using where:使用where關鍵字查找
  5. impossible where:子句的值總的false,不能用來獲取任何元組

索引優化案例

  • 單表建立索引,查詢的字段不要出現範圍否則會出現索引失效的情況
  • 兩個表連接查詢建立索引,索引一般建在從表上,左連接,建立在右邊;右連接,建立在左邊。

索引失效情況(應該避免)

  • 全值匹配我最愛(查詢條件完全符合索引順序)
  • 最佳左前綴法則:如果索引了多列,要遵守最左前綴法則。指的是查詢從索引的最左列開始並且 不跳過索引列(類別火車,火車頭)
  • 不能在所有列上做任何操作(計算,函數,(自動or手動)類型轉換),會導致索引失效,導致全表掃描
  • 存儲引擎不能使用索引中範圍條件右邊的列
  • 儘量使用覆蓋索引(只訪問索引的查詢),減少select *
  • 在使用不等於(!= 或者<>)的時候無法使用索引導致全表掃描
  • is null 或者is not null 也無法使用索引
  • like以通配符開頭(’%abcd’),MySQL索引會失效會變成全表掃描
  • 字符串不加單引號索引也會失效
  • 少用or,用了它連接會導致索引失效

阿里巴巴規範

  • 推薦】:SQL性能優化的目標:至少要達到rang級別,要求是ref級別,如果可以是consts最好。
    說明consts單表中最多隻有一個匹配行(主鍵或者唯一索引),在優化階段即可讀取到數據。
    ref指的是使用普通的索引(normal index)
    rang對索引進行範圍檢索
    反例:explain表的結果,type=index,索引物理文件全掃描,速度非常慢,這個index級別比較range還低,與全表掃描是小巫見大巫
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章