explain這是這次想要了解的重點命令,用於檢視mysql中查詢sql語句的執行計畫,用來對sql進行優化,以最合理的方式寫sql語句
一條標準的sql查詢語句:
explain select id from user_customer where id=1\g;
得到的結果:
*************************** 1. row ***************************
id: 1
select_type: ******
table: user_customer
partitions: null
type: const
possible_keys: primary
key: primary
key_len: 4
ref: const
rows: 1
filtered: 100.00
extra: using index
從上面可以看到所有的引數,下面一一進行說明:
idselect查詢的識別符號,每個select都會被自動分配乙個唯一的識別符號
select_type
select 查詢的型別,常見的值如下:
******:表示此查詢不包含union查詢或子查詢
primary:表示此查詢是最外層的查詢
union:表示此查詢是union的第二或隨後的查詢
dependent union:union中的第二個或後面的查詢語句,取決於外面的查詢
union result:union的結果
subquery:子查詢中的第乙個select
dependend subquery:子查詢中的第乙個select,取決於外面的查詢,即子查詢依賴於外層查詢的結果
derived:被驅動的select子查詢(子查詢位於from子句)
materialized:被物化的子查詢
table
查詢涉及到的資料表或衍生表
type
type欄位比較重要,它標識了查詢是否高效,是使用了全表掃瞄還是索引掃瞄等等
system:表中只有一條資料,這個型別是特殊的const型別
const:針對主鍵或唯一索引的等值查詢掃瞄,最多隻返回一條資料。const查詢的速度非常快,因為它僅僅讀取一次即可,如下面的sql語句
select * from user_customer where id=5;
ref:此型別通常出現在多表的join查詢,針對於非唯一或非主鍵索引,或者是使用了最左字首規則索引的查詢
select * from user_customer where first_name='123' and last_name='456';
explain select * from migrations,user_customer where migrations.batch=user_customer.uid and cid>1\g;
eq_ref:通常出現在多表的join查詢,對於對於前表的每乙個結果,都只能匹配到後表的一行結果,並且查詢的比較操作是=,查詢效率較高
explain select * from migrations,user_customer where migrations.batch=user_customer.uid \g; //前表的資料在後表中都有匹配
range:range表示的索引範圍查詢,通過索引字段範圍獲取表中部分資料記錄,這個型別通常出現在=, <>, >,
當type是range時,那麼explain輸出的ref欄位為null,並且ken_len欄位為此次查詢中使用到的索引的最長的那個
> int的長度是4位元組,bigint的長度是8位元組;字串根據欄位的長度可以計算出長度(**utf每個字元占用3位元組,如果是varchar**);如果字段允許null則會增加乙個位元組的大小
index:表示掃瞄的時候僅僅掃瞄了索引,而不掃瞄資料;也就是說在查詢資料的時候直接在索引樹中就可以獲取到,在這種情況下的時候,extra欄位會顯式using index
all:表示全表掃瞄,是所有這些屬***能最差的乙個
type型別的效能比較
all < index < range ~ index_merge < ref < eq_ref < const < system
possible_keys
表示在查詢的過程中有可能使用到的keys
ken_len
表示查詢優化器使用到了的索引的位元組數,這個字段可以評估出組合索引是否被完全使用到,或只有最左部分欄位被使用到,key_len的計算規則如下:
字串char(n):固定長度,n字元長度,根據不同的編碼n2或n3的位元組
varchar(n):變長長度,在實際計算儲存大小的時候,n小於255則用1位元組儲存長度,大於255則用2位元組儲存長度
數值型別
tinyint(n):1位元組
smallint(n):2位元組
mediumint(n):3位元組
int(n):4位元組
bitint(n):8位元組
時間型別
date:3位元組
timestamp:4位元組
datetime:8位元組
字段屬性:
null屬性占用乙個位元組,如果欄位是not null的,則不會占用這額外的一位元組
在數值型別中,是預留出了一位去儲存數值的符號
rows
mysql查詢優化器根據統計資訊,估算sql要查詢結果集需要掃瞄讀取的資料行數,這個值可以直觀的反映出sql的效率,原則上rows數值越小越好
extra
在sql中很多額外的資訊會在extra欄位中體現:
using filesort
當extra欄位中有using filesort時,表示mysql需要額外的排序操作,不能通過索引順序達到排序效果;在sql語句中使用order by進行排序的時候,如果沒有很好的使用到定值和最左排序的話,會出現這種情況
using index condition
這是mysql5.6的新特性,叫索引條件推送,只是針對於二級索引。
在一般情況下,mysql伺服器都會將儲存引擎處理完成的資料返回給服務層後在應用where條件進行過濾,但是當mysql篩選到where條件中的第乙個條件篩選的方式是類似於範圍查詢,就是like,
查詢想要獲取的字段都是*
using index
「覆蓋索引掃瞄」,表示查詢在索引樹上就可以找到所需要的資料,而不需要掃瞄底層的葉子節點資料,這種情況效能很好
只出現了這個的時候表示效能很好;如果這個和using where同時出現的話,表示先在儲存引擎中使用索引進行篩選,再在mysql服務中進行條件篩選
using temporary
在查詢的時候使用臨時表,一般出現排序,分組和多表join的情況,查詢效率不高,建議進行優化
using where
使用了where從句來限制哪些行將與下乙個表匹配或者是返回給使用者
extra列出現using where表示mysql伺服器將儲存引擎返回服務層以後再應用where條件過濾
有一種情況,資料表中資料量很大,查詢的條件在資料表中佔的比例也很高,本來在原則上可以使用索引,但是因為該查詢記錄佔表中比例很大,mysql會不對該sql使用索引,這種情況可以在查詢語句後面使用limit進行限制
using mrr
這也是mysql5.6新增的特性, multi-range read(多範圍讀),針對基於輔助/第二索引的查詢,減少隨機io,並且將隨機io轉換為順序io,提高查詢效率
在基於mysql中的innodb的資料儲存方式才用的是b+tree,二級索引的儲存順序與主鍵的順序是不一致的,開啟了mrr之後,mysql將根據輔助結果集獲取的結果集根據主鍵進行排序,將亂序化為有序,可以用主鍵訪問基表,將隨機讀轉換為順序讀,多頁資料記錄可一次性讀入或根據此次的主鍵範圍分次讀入,以減少io操作,提高查詢效率
not exists
mysql優化了left join,一旦它找到了匹配left join標準的行,就不再搜尋了
mysql 查詢執行計畫 MySql執行計畫的檢視
一。什麼是資料庫執行計畫 利用乙個sql語句,你可能要server取出所有news表中的資訊.當server收到的這條sql的時候,第一件事情並不是解析它.如果這條sql沒有語法錯誤,server才會繼續工作.server會決定最好的計算方式.server會選擇,是讀整個news表好呢,還是利用索引...
Solr查詢引數 分頁 start 與 rows
摘要 在solr中,用start引數控制返回第一條記錄在完整找到結果中的偏移位置,用rows 指定返回結果最多有多少條記錄,配合start來實現分頁。solr缺省會給每一次查詢加上分頁效果 start為0,rows為10.也就是返回前十條記錄。很多境況下這樣的結果就夠用了,如果不滿足業務要求,就需要...
sql server 查詢計畫
在你的執行sql 語句之前加上 下面這句話 就可以列出相應的執行計畫 set statistics profile on 執行計畫簡單說明 rows 表示在乙個執行步驟中,所產生的記錄條數。真實資料,非預期 executes 表示某個執行步驟被執行的次數。真實資料,非預期 stmt text 表示要...