MySQL之SQL優化詳解(二)

MySQL之SQL優化詳解(二)

1. SQL的執行順序

1.1 手寫順序

 

1.2 機讀順序

 

 

2. 七種join

 

3. 索引

3.1 索引初探

  • 是什麼: 排好序的快速查找數據結構sql

  • 兩個主要的索引結構: B+tree 索引和哈希索引。數據庫

  • 如何建: 1. ALTER TABLE table_name ADD INDEX index_name (column_list); 2. CREATE INDEX index_name ON table_name (column_list);緩存

 

優勢: 相似大學圖書館建書目索引,提升了檢索效率,下降了數據庫IO,同時還能夠經過索引進行排序,下降數據排序的成本,下降了CPU的消耗數據結構

缺點: 雖然索引大大提升了查詢速度,同時卻會下降更新表的速度,如對錶進行 insertupdatedelete,由於更新表時不只要保存數據,還要保存一下索引文件每次更新添加了索引列的字段。性能

 

3.2 索引分類

1.主鍵索引:主鍵是一種惟一性索引,但它必須指定爲PRIMARY KEY,每一個表只能有一個主鍵優化

ALTER TABLE table_name ADD PRIMARY KEY (column_list)

2.惟一索引:索引列的全部值都只能出現一次,即必須 惟一,值能夠爲 空code

ALTER TABLE table_name ADD UNIQUE (column_list)

3.普通索引:基本的索引類型,值能夠爲空,沒有惟一性的限制blog

ALTER TABLE table_name ADD INDEX index_name (column_list);

4.全文索引: 全文索引的索引類型爲 FULLTEXT,全文索引只能建立在CHAR、VARCHAR、TEXT類型的字段上。查詢數據量較大的字符串類型字段時,使用全文索引能夠提升查詢速度排序

ALTER TABLE table_name ADD FULLTEXT INDEX index_name(column_list);

 

3.3 建與不建

對於MySQL的索引建立,咱們常常有疑慮,那麼何時該建何時不應建呢?

哪些狀況須要建立索引

  1. 主鍵自動建立惟一索引

  2. 頻繁做爲查詢條件的字段應該建立索引

  3. 查詢中與其它表關聯的字段,外鍵關係創建索引

  4. 查詢中排序的字段,排序字段若經過索引去訪問將大大提升排序速度

  5. 查詢中統計或者分組字段

 

哪些狀況不須要建索引

  1. 頻繁更新的字段不適合建立索引
  2. where 條件用不到的字段不適合建立索引
  3. 注意,若是某個數據列包含許多重複的內容,爲它創建索引就沒有太大的實際效果

 

4. 性能分析Explain

Explain簡稱執行計劃,使用Explain關鍵字能夠模擬優化器執行SQL查詢語句

用法:explain + SQL


 

1. id:select查詢的序列號,包含一組數字,表示查詢中執行select子句或操做表的順序

① id 相同執行順序由上至下

② id 不一樣,若是是子查詢,id的序號會遞增,id值越大優先級越高,越先被執行

③ id相同不相同,不相同

注:id若是相同,能夠認爲是一組,從上往下順序執行;在全部組中,id值越大,優先級越高,越先執行

 

2. select_type:查詢的類型,主要是用於區分 普通查詢、聯合查詢、子查詢等的複雜查詢

  • simple:簡單的select 查詢,查詢中不包含子查詢或者 union
  • primary:查詢中若包含任何複雜的子部分,最外層查詢則被標記爲
  • subquery:在selectwhere列表中包含了子查詢
  • derived:在from 列表中包含的子查詢被標記爲 derived(衍生)
  • union:若第二個select出如今以後,則被標記爲 union(若union 包含from 子句的子查詢中,外層select將被標記爲:derived)
  • union result:從union 表獲取結果的 select

 

3. table:顯示這一行的數據是關於哪張表的

4. type:訪問類型排列,顯示查詢使用了何種類型

從好到壞,system > const > eq_ref > ref > range > index > all

  • system:表只有一行記錄(等於系統表),這是const 類型的特列,平時不會出現,這個也能夠忽略不計
  • const:表示經過索引一次就找到了,const 用於比較 primary key或者unique索引
  • eq_ref:惟一性索引掃描,對於每一個索引鍵,表中只有一條記錄與之匹配。常見於主鍵或惟一索引掃描
  • ref:非惟一性索引掃描,返回匹配某個單獨值的全部行,本質上也是一種索引訪問
  • range:只檢索給定範圍的行,使用一個索引來選擇行。key 列顯示使用了哪一個索引,通常就是在你的where語句中出現了 between、<、>、in等的查詢
  • index:Full Index Scan,index與 all 區別爲 index 類型只遍歷索引樹
  • all:Full Table Scan,將遍歷全表以找到匹配的行

 

5. possible_key:顯示可能應用在這張表的索引,一個或多個。(但不必定被實際應用)

6. key:實際使用的索引,若是爲null,則沒有使用索引。

查詢中若使用了覆蓋索引,則該索引與查詢的select字段重疊

 

7. key_len:表示索引中使用的字節數

8. ref:顯示索引的哪一列被使用,若是可能的話,是一個常數,哪些列或常量被用於查找索引列上的值

注:由key_len可知t1表的idx_col1_col2被充分使用,col1匹配t2表的col1col2匹配了一個常量,即 'ac'

 

9. rows:根據表統計信息及索引選用狀況,大體估算出找到所需的記錄所須要讀取的行數

10. extra:包含不適合在其餘列中顯示但十分重要的額外信息

  • Using filesort (劣): mysql 會對數據使用一個外部的索引排序(文件排序),而不是照表內的索引順序進行讀取

 

  • Using temporary (劣):使了用臨時表保存中間結果,MySQL在對查詢結果排序時使用臨時表。常見於排序 order by 和分組查詢 group by

 

  • Using index (優):表示相應的select操做中使用了覆蓋索引(Covering Index),避免訪問了表的數據行,效率不錯!
  • Using where:代表使用了where 過濾
  • Using join buffer:代表使用了鏈接緩存
  • impossible where:where子句的值老是false,不能用來獲取任何數據

 

  • select tables optimized away:select操做已經優化到不能再優化了(MySQL根本沒有遍歷表或索引就返回數據了
  • distinct:在select部分使用了distinc關鍵字

心法:

針對explain命令生成的執行計劃,這裏有一個查看心法。咱們能夠先從查詢類型type列開始查看,若是出現all關鍵字,後面的內容就均可以不用看了,表明全表掃描。再看key列,看是否使用了索引,null表明沒有使用索引。而後看rows列,該列用來表示在SQL執行過程當中被掃描的行數,該數值越大,意味着須要掃描的行數越多,相應的耗時越長,最後看Extra列,在這列中要觀察是否有Using filesort 或者Using temporary 這樣的關鍵字出現,這些是很影響數據庫性能的。

相關文章
相關標籤/搜索