mysql相關優化
技術標籤:MySQL集合
MySQL優化
1.索引sql語句
檢視索引:
show index from 表名;
建立單例索引:
create index 索引名 on 表名(列1,列2,……);
刪除索引:
drop index 索引名 on 表名
2.SQL優化
2.1explain分析執行計劃
通過 explain或者 desc獲取 MySQL如何執行 SELECT 語句的資訊,包括在 SELECT 語句執行過程中表如何連線和連線的順序。
欄位 | 含義 |
---|---|
id | select查詢的序列號,是一組數字,表示的是查詢中執行select子句或者是操作表的順序。 |
select_type | 表示 SELECT 的型別,常見的取值有 SIMPLE(簡單表,即不使用表連線或者子查詢)、PRIMARY(主查詢,即外層的查詢)、UNION(UNION 中的第二個或者後面的查詢語句)、SUBQUERY(子查詢中的第一個 SELECT)等 |
table | 輸出結果集的表 |
type | 表示表的連線型別,效能由好到差的連線型別為( system —> const -----> eq_ref ------> ref -------> ref_or_null----> index_merge —> index_subquery -----> range -----> index ------> all ) |
possible_keys | 表示查詢時,可能使用的索引 |
key | 表示實際使用的索引 |
key_len | 索引欄位的長度 |
rows | 掃描行的數量 |
extra | 執行情況的說明和描述 |
2.1.1 explain 之 id
id 欄位是 select查詢的序列號,是一組數字,表示的是查詢中執行select子句或者是操作表的順序.
id 有相同,也有不同,同時存在。id相同的可以認為是一組,從上往下順序執行;在所有的組中,id的值越大,優先順序越高,越先執行。
2.2.2 explain 之 select_type
表示 SELECT 的型別,常見的取值,如下表所示:
select_type | 含義 |
---|---|
SIMPLE | 簡單的select查詢,查詢中不包含子查詢或者UNION |
PRIMARY | 查詢中若包含任何複雜的子查詢,最外層查詢標記為該標識 |
SUBQUERY | 在SELECT 或 WHERE 列表中包含了子查詢 |
DERIVED | 在FROM 列表中包含的子查詢,被標記為 DERIVED(衍生) MYSQL會遞迴執行這些子查詢,把結果放在臨時表中 |
UNION | 若第二個SELECT出現在UNION之後,則標記為UNION ; 若UNION包含在FROM子句的子查詢中,外層SELECT將被標記為 : DERIVED |
UNION RESULT | 從UNION表獲取結果的SELECT |
2.2.3 explain 之 table
展示這一行的資料是關於哪一張表的
2.2.4 explain 之 type
type 顯示的是訪問型別,是較為重要的一個指標,可取值為:
type | 含義 |
---|---|
NULL | MySQL不訪問任何表,索引,直接返回結果 |
system | 表只有一行記錄(等於系統表),這是const型別的特例,一般不會出現 |
const | 表示通過索引一次就找到了,const 用於比較primary key 或者 unique 索引。因為只匹配一行資料,所以很快。如將主鍵置於where列表中,MySQL 就能將該查詢轉換為一個常亮。const於將 “主鍵” 或 “唯一” 索引的所有部分與常量值進行比較 |
eq_ref | 類似ref,區別在於使用的是唯一索引,使用主鍵的關聯查詢,關聯查詢出的記錄只有一條。常見於主鍵或唯一索引掃描 |
ref | 非唯一性索引掃描,返回匹配某個單獨值的所有行。本質上也是一種索引訪問,返回所有匹配某個單獨值的所有行(多個) |
range | 只檢索給定返回的行,使用一個索引來選擇行。 where 之後出現 between , < , > , in 等操作。 |
index | index 與 ALL的區別為 index 型別只是遍歷了索引樹, 通常比ALL 快, ALL 是遍歷資料檔案。 |
all | 將遍歷全表以找到匹配的行 |
結果值從最好到最壞以此是:
NULL > 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
一般來說, 我們需要保證查詢至少達到 range 級別, 最好達到ref 。
2.2.6 explain 之 key
possible_keys : 顯示可能應用在這張表的索引, 一個或多個。
key : 實際使用的索引, 如果為NULL, 則沒有使用索引。
key_len : 表示索引中使用的位元組數, 該值為索引欄位最大可能長度,並非實際使用長度,在不損失精確性的前提下, 長度越短越好 。
2.2.7 explain 之 rows
掃描行的數量。
2.2…8 explain 之 extra
其他的額外的執行計劃資訊,在該列展示 。
extra | 含義 |
---|---|
using filesort | 說明mysql會對資料使用一個外部的索引排序,而不是按照表內的索引順序進行讀取, 稱為 “檔案排序”, 效率低。 |
using temporary | 使用了臨時表儲存中間結果,MySQL在對查詢結果排序時使用臨時表。常見於 order by 和 group by; 效率低 |
using index | 表示相應的select操作使用了覆蓋索引, 避免訪問表的資料行, 效率不錯。 |
3.索引優化
1.全職匹配,對索引中所有列都指定具體值
2.最左字首法則
- 如果所有走了多列,要遵守最左字首法則,指的是查詢從索引的最左前端開始,並且不跳過索引中的列
3.範圍查詢右邊的列,不能使用索引
4.不要在索引列上進行運算操作,否則索引會失效
5.查詢的時候,字串不加單引號,會造成索引失效
- 在查詢時,沒有對字串加單引號,MySQL的查詢優化器,會自動的進行隱式轉換,造成索引失效
6.儘量使用覆蓋索引,避免使用select *
7.使用or分割的條件,如果or之前的條件中的列有索引,而後面的列沒有索引,那麼設涉及到的索引都不會使用到
8.以%開頭的like模糊匹配,索引會失效
- 如果僅僅時尾部進行模糊匹配,索引不會失效,如果是頭部模糊匹配,索引會失效
- 解決方案:通過覆蓋所有來解決
9.如果mysql評估使用索引比全錶慢,則不使用索引
10.is null,is not null,有時會索引失效
11.in走索引,not in不走索引
12.單列索引和複合索引(儘量使用符合索引)
4.SQL優化
4.1大量資料匯入
- 主鍵順序插入
因為InnoDB型別的表是按照主鍵的順序儲存的,所以將匯入的資料按照主鍵的順序排列,可以有效的提高匯入資料的效率。如果InnoDB表沒有主鍵,那麼系統會自動預設建立一個內部列作為主鍵,所以如果可以給表建立一個主鍵,將可以利用這點,來提高匯入資料的效率。
-
關閉唯一性校驗
在匯入資料前執行 SET UNIQUE_CHECKS=0,關閉唯一性校驗,在匯入結束後執行SET UNIQUE_CHECKS=1,恢復唯一性校驗,可以提高匯入的效率。
-
手動提交事務
如果應用使用自動提交的方式,建議在匯入前執行 SET AUTOCOMMIT=0,關閉自動提交,匯入結束後再執行 SET AUTOCOMMIT=1,開啟自動提交,也可以提高匯入的效率。
4.2優化insert語句
- 如果需要同時對一張表插入很多行資料時,應該儘量使用多個值表的insert語句,這種方式將大大的縮減客戶端與資料庫之間的連線、關閉等消耗。使得效率比分開執行的單個insert語句快
- 在事務中進行資料插入。
- 資料有序插入
4.3order by語句優化
兩種排序方式:
- 通過對返回資料進行排序,也就是通常說的 filesort 排序,所有不是通過索引直接返回排序結果的排序都叫 FileSort 排序。
- 通過有序索引順序掃描直接返回有序資料,這種情況即為 using index,不需要額外排序,操作效率高。
儘量減少額外的排序,通過索引直接返回有序資料。
where 條件和Order by 使用相同的索引,並且Order By 的順序和索引順序相同, 並且Order by 的欄位都是升序,或者都是降序。
否則肯定需要額外的操作,這樣就會出現FileSort。
4.4group by語句優化
由於GROUP BY 實際上也同樣會進行排序操作,而且與ORDER BY 相比,GROUP BY 主要只是多了排序之後的分組操作。當然,如果
在分組的時候還使用了其他的一些聚合函式,那麼還需要一些聚合函式的計算。所以,在GROUP BY 的實現過程中,與 ORDER BY 一
樣也可以利用到索引。如果查詢包含 group by 但是使用者想要避免排序結果的消耗, 則可以執行order by null 禁止排序。
select age,count(*) from emp group by age order by null;
4.5優化or條件
- UNION 語句的 type 值為 ref,OR 語句的 type 值為 range,可以看到這是一個很明顯的差距
- UNION 語句的 ref 值為 const,OR 語句的 type 值為 null,const 表示是常量值引用,非常快
這兩項的差距就說明了 UNION 要優於 OR 。
4.6優化巢狀(子)查詢
子查詢是可以被更高效的連線(JOIN)替代。
連線(Join)查詢之所以更有效率一些 ,是因為MySQL不需要在記憶體中建立臨時表來完成這個邏輯上需要兩個步驟的查詢工作。
5.MYSQL常用查詢
查詢當前資料庫支援的儲存引擎: show engines;
檢視Mysql資料庫預設的儲存引擎: show variables like '%storage_engine%'