1.mysql query optimizer(mysql服務層自帶的優化器)
1)mysql中有專門負責優化select語句的優化器模組,主要功能:通過計算分析系統中收集到的統計資訊,為客戶端
請求的query提供他認為最優的執行計畫(他認為最優的資料檢索方式,但不見得是dba認為最優的,這部分最耗費時間)
2)當客戶端向mysql請求一條query,命令解析器模組完成請求分類,區別出是select並**給mysql query optimizer時,
mysql query optimizer首先會對整條query進行優化,處理掉一些常量表示式的預算,直接換算成常量值。並對query中
的查詢條件進行簡化和轉換,如去掉一些無用或顯而易見的條件、結構調整等。然後分析query中的hint資訊(如果有),
看顯示hint資訊是否可以完全確定該query的執行計畫。如果沒有 hint或hint資訊還不足以完全確定執行計畫,則會讀取所涉及
物件的統計資訊,根據query進行寫相應的計算分析,然後再得出最後的執行計畫
2.mysql常見的瓶頸
1)cpu:cpu在飽和的時候一般發生在資料裝入記憶體或從磁碟上讀取資料時候
2)io:磁碟i/o瓶頸發生在裝入資料遠大於記憶體容量的時候
3)伺服器硬體的效能瓶頸:top,free,iostat和vmstat來檢視系統的效能狀態
3.explain
1)能幹嘛
a.表的讀取順序
b.資料讀取操作的操作型別
c.哪些索引可以使用
d.哪些索引被實際使用
e.表之間的引用
f.每張表有多少行被優化器查詢
2)怎麼用
a.explain + sql語句
b.執行計畫包含的資訊
idselect查詢的序列號,包含一組數字,表示查詢中執行select子句或操作表的順序
存在三種情況
1> id相同,執行順序由上至下
2> id不同,如果是子查詢,id的序號會遞增,id值越大優先順序越高,越先被執行
3> id相同不同,同時存在(id如果相同,可以認為是一組,從上至下順序執行,在所有組中,id越大,優先順序越高,越先執行)
dervied(衍生)
型別等級(主要是用於區別普通查詢、聯合查詢、子查詢等的複雜查詢)
1.******:簡單的select查詢,查詢中不包含子查詢或者union
2.primary:查詢中若包含任何複雜的子部分,最外層查詢則被標記
3.subquery:在select或where列表中包含了子查詢
4.derived:在from列表中包含的子查詢被標記為derived(衍生) ,mysql會遞迴執行這引起子查詢,把結果放在臨時表裡
5.union:若第二個select出現在union之後,則被標記為union;若union包含在from子句的子查詢中,外層select將被標記為:derived(衍生)
6.union result:從union表獲取結果的select
table
顯示這一行的資料是關於哪張表的
type
訪問型別:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > all
常見的從最好到最差排序:system > const > eq_ref > ref > range > index > all
system:表只有一行記錄(等於系統表),這是const型別的特列,平時不會出現,這個也可以忽略不計
const :表示通過索引一次就找到了,const用於比較primary key或者unique索引。因為只匹配一行資料,所以很快。如將主鍵置於where列表中,mysql就能將該查詢轉換為乙個常量
eq_ref:唯一性索引掃瞄,對於每個索引鍵,表中只有一條記錄與之匹配。常見於主鍵或唯一索引掃瞄
ref:非唯一性索引掃瞄,返回匹配某個單獨值的所有行,本質上也是一種索引訪問,它返回所有匹配某個單獨值的行,然而,它可能會找到多個符合條件的行,所以他應該屬於查詢和掃瞄的混合體
range:只檢索給定範圍的行,使用乙個索引來選擇行。 key列顯示使用了哪個索引,一般就是在你的where語句**現了between、、in等的查詢
這種範圍掃瞄索引比全表掃瞄要好,因為它只需要開始於索引的某一點,而結束於另一點,不用掃瞄全部索引
index:full index scan,index與all區別為index型別只遍歷索引樹。這通常比all快,因為索引檔案通常比資料檔案小(all與index都是讀全表,但index是從索引中讀取的,而all是在硬碟中讀的)。
all:full index scan,將遍歷全表以找到匹配的行
一般來說,得保證查詢至少達到range級別,最好能達到ref
possible_keys
顯示可能應用在這張表中的索引,乙個或多個,查詢涉及到的字段,若存在索引,則該索引將被列出,但不一定被查詢實際使用
key實際使用的索引,如果為null,則沒有使用索引,查詢中若使用了覆蓋索引(建表索引欄位與查詢出的字段吻合),則該索引僅出現在key列表中
覆蓋索引(索引覆蓋):就是select的資料列只用從索引中就能夠取得,不必讀取資料行,mysql可以利用索引返回select列表中的字段,而不必根據索引再次讀取資料檔案,換句話說查詢列要被所建的索引覆蓋
表示索引中使用的位元組數,可通過該列計算查詢中使用的索引的長度。在不損失精確性的情況下,長度越短越好
key_len顯示的值為索引欄位的最大可能長度,並非實際使用長度,即key_len是根據表定義計算而得,不是通過表內檢索出的
ref顯示索引的哪一列被使用了,如果可能的話,是乙個常數,哪些列或常量被用於查詢索引列上的值
rows
根據表統計資訊及索引選用情況,大致估算出找到所需的記錄所需要讀取的行數
extra
1> using filesort:說明 mysql會對資料使用乙個外部的索引排序(沒有使用到索引),而不是按照表內的索引順序進行讀取,mysql中無法利用索引完成的排序操作稱為「檔案排序」
2> using temporary:使用了臨時表儲存中間結果,mysql在對查詢結果排序時使用臨時表。常見於排序order by 和分組查詢group by
3>using index:表示相應的select操作中使用了覆蓋索引,避免訪問了表的資料行,效率不錯。
如果同時出現using where,表明索引被用來執行索引鍵值的查詢。
如果沒有同時出現using where,表時索引用來讀取資料而非執行查詢動作
4> using where:表明使用了where過濾
5> using join buffer:使用了連線快取
6> impossible where:where子句的值總是false,不能用來獲取任何元組
7> select tables optimized away:在沒有group by子句的情況下,基於索引優化min/max操作或者對於myisam儲存引擎優化count(*)操作,不必等到執行階段再進行計算。
查詢執行計畫生成的階段即完成優化。
8> distinct:優化distinct操作,在找到第一匹配的元組後即停止找同樣值的動作
讀高效能mysql筆記
效能監控的好工具 newrelic 效能分析的好工具 percona toolkit show variables like slow show full processlist set profiling 1 select from score cal unsuccessed show profi...
mysql幻讀 mysql 幻讀
幻讀 phantom read 是指當使用者讀取某一範圍的資料行時,b事務在該範圍內插入了新行,當使用者再讀取該範圍的資料行時,會發現有新的 幻影 行。innodb和falcon儲存引擎通 過多版本併發控制機制解決了幻讀問題。a事務讀取了b事務已經提交的新增資料,此時 a 還沒有提交,當前提交後,也...
mysql效能優化 mysql效能優化
優化方式 1.空間換時間 冗餘 2.時間換空間 字段優先使用型別 int date char varchar text 索引型別 btree索引 hash索引 索引的葉子下,存放乙個資訊指向所在行的資料位址。btree有利於範圍查詢,hash有利於精確查詢。btree用的更多一些。btree索引的常...