电竞比分网-中国电竞赛事及体育赛事平台

分享

高級測試工程師是如何解決sql索引引起的性能問題?

 曾淼Mark 2019-01-04

小編導讀:

一、索引的利弊

二、索引使用原則

三、索引分析利器explain

四、引起索引失效的一些因素



在性能測試中遇到性能瓶頸最多的地方就是數(shù)據(jù)庫這塊,而數(shù)據(jù)庫的問題大部分都是由于索引使用不當引起的,根據(jù)以往遇到的索引問題做個簡單的總結(jié):



一、索引的利弊

索引的好處:

索引能夠極大地提高數(shù)據(jù)檢索的效率,讓Query 執(zhí)行得更快,也能夠改善排序分組操作的性能,在進行排序分組操作中利用好索引,將會極大地降低CPU資源的消耗。

索引的弊端:

1、更新數(shù)據(jù)庫時會更新索引,這樣,最明顯的資源消耗就是增加了更新所帶來的 IO 量和調(diào)整索引所致的計算量;

2、索引也會占用一定的存儲空間,有些時候索引所占的空間有可能超過數(shù)據(jù)所占的空間。



二、索引使用原則

1、索引可以改善查詢,但會減慢更新,索引不是越多越好,最好不超過字段數(shù)的20%(在數(shù)據(jù)增、刪、改比較頻繁的表中,索引數(shù)量不應(yīng)超過5個)這一點已經(jīng)在上面介紹過,這里就不做太多介紹。

2、離散程度越小,不適合加索引,例如:不要給性別建索引 status這樣字段建索引;

3、在數(shù)據(jù)量較少且訪問頻率不高的情況下,如只有一百行記錄以下的表不需要建立索引。因為在數(shù)據(jù)量少的情況下,使用全表掃描效果比走索引更好,這就好比一本只有5頁的書,如果我們想找其中一個章節(jié),我們一般不會通過目錄去尋找,而是直接去找了。

4、唯一索引:在建立索引的字段所有數(shù)值都具有唯一性特點的情況下,建立唯一索引(unique index)代替普通索引,唯一索引(unique index)查詢效率比普通索引查詢效率更高,可以大幅提升查詢速度。

5、避免建立兩個或以上功能相同索引。例如已經(jīng)建立字段A、B兩個字段的索引,應(yīng)該避免再建立字段A的單獨索引。兩個索引之間,對相同的查詢都會起到相同的作用。建立兩個功能相同的索引,反而會容易引起數(shù)據(jù)庫產(chǎn)生錯誤的查詢計劃,降低查詢效率。

6、選擇正確的組合索引字段順序,最常用的查詢字段和選擇性、區(qū)分度較高的字段,應(yīng)該作為索引的前導字段使用。假設(shè)存在組合索引it1(c1,c2),查詢語句select * from t1 where c1=1 and c2=2能夠使用該索引。查詢語句select *from t1 where c1=1也能夠使用該索引。但是,查詢語句select * from t1 where c2=2不能夠使用該索引,因為沒有組合索引的引導列,即,要想使用c2列進行查找,必需出現(xiàn)c1等于某值,所以在在添加聯(lián)合索引的時候盡量將常用的字段放到最前面。

7、合適的字段數(shù),組合索引的字段數(shù)不適宜較多,較多的組合索引字段數(shù)會降低索引查詢效率,組合索引字段數(shù)應(yīng)不多于3個,除業(yè)務(wù)特點需要建立多字段的組合主鍵例外。



三、索引分析利器explain

在做性能測試的過程中經(jīng)常遇到一些數(shù)據(jù)庫的問題,通常使用慢查詢?nèi)罩究梢哉业綀?zhí)行效果比較差的sql,但是僅僅找到這些sql是不行的,我們需要協(xié)助開發(fā)人員分析問題所在,這就經(jīng)常要用到explain。

explain顯示了mysql如何使用索引來處理select語句以及連接表??梢詭椭x擇更好的索引和寫出更優(yōu)化的查詢語句。

使用方法,在select語句前加上explain就可以了:


explain列的解釋:

1、idSELECT識別符。這是SELECT的查詢序列號,若沒有子查詢和聯(lián)合查詢,id則都是1,并且Mysql會按照id從大到小的順序執(zhí)行query,在id相同的情況下,則從上到下執(zhí)行。

2、table顯示這一行的數(shù)據(jù)是關(guān)于哪張表的。

3、type這是重要的列,顯示連接使用了何種類型。

1>system: 表只有一行:system表。這是const連接類型的特殊情況

2>const: 表最多有一個匹配行,它將在查詢開始時被讀取。因為僅有一行,在這行的列值可被優(yōu)化器剩余部分認為是常數(shù)。const表很快,因為它們只讀取一次!(索引可以是主鍵或惟一索引)。

3>eq_ref: 在連接中,MYSQL在查詢時,從前面的表中,對每一個記錄的聯(lián)合都從表中讀取一個記錄,它在查詢使用了索引為主鍵或惟一鍵的全部時使用

4>ref: 這個連接類型只有在查詢使用了不是惟一或主鍵的鍵或者是這些類型的部分(比如,利用最左邊前綴)時發(fā)生。對于之前的表的每一個行聯(lián)合,全部記錄都將從表中讀出。這個類型嚴重依賴于根據(jù)索引匹配的記錄多少(越少越好)。

5>range: 這個連接類型使用索引返回一個范圍中的行,比如使用><查找東西時發(fā)生的情況

6>index: 這個連接類型對前面的表中的每一個記錄聯(lián)合進行完全掃描(比ALL更好,因為索引一般小于表數(shù)據(jù))

7>ALL: 這個連接類型對于前面的每一個記錄聯(lián)合進行完全掃描,這一般比較糟糕,應(yīng)該盡量避免。

Explaintype顯示的是訪問類型,是較為重要的一個指標,結(jié)果值從好到壞依次是:

system > const > eq_ref > ref > range > index > ALL

4、possible_keys顯示可能應(yīng)用這張表中的那個索引。如果為空,沒有可能的索引??梢詾橄嚓P(guān)的域從WHERE語句中選擇一個合適的語句。

5、key實際使用的索引。如果為NULL,則沒有使用索引。很少的情況下,MYSQL會選擇優(yōu)化不足的索引。這種情況下,可以在SELECT語句中使用USEINDEXindexname)來強制使用一個索引或者用IGNORE INDEXindexname)來強制MYSQL忽略索引。

6、key_len使用的索引的長度。在不損失精確性的情況下,長度越短越好。

7、ref顯示索引的哪一列被使用了,如果可能的話,是一個常數(shù)。

8、rowsMYSQL認為必須檢查的用來返回請求數(shù)據(jù)的行數(shù)。

9、Extra關(guān)于MYSQL如何解析查詢的額外信息。

extra列返回值描述如下:

  • Distinct:一旦MYSQL找到了與行相聯(lián)合匹配的行,就不再搜索了

  • Not exists: MYSQL優(yōu)化了LEFT JOIN,一旦它找到了匹配LEFT JOIN標準的行,就不再搜索了。

  • Range checked for each Recordindex map:#:沒有找到理想的索引,因此對于從前面表中來的每一個行組合,MYSQL檢查使用哪個索引,并用它來從表中返回行。這是使用索引的最慢的連接之一。

  • Using filesort: 看到這個的時候,查詢就需要優(yōu)化了。MYSQL需要進行額外的步驟來發(fā)現(xiàn)如何對返回的行排序。它根據(jù)連接類型以及存儲排序鍵值和匹配條件的全部行的行指針來排序全部行。

  • Using index: 列數(shù)據(jù)是從僅僅使用了索引中的信息而沒有讀取實際的行動的表返回的,這發(fā)生在對表的全部的請求列都是同一個索引的部分的時候

  • Using temporary 看到這個的時候,查詢需要優(yōu)化了。這里,MYSQL需要創(chuàng)建一個臨時表來存儲結(jié)果,這通常發(fā)生在對不同的列集進行ORDER BY上,而不是GROUP BY上。

  • Using where使用了WHERE從句來限制哪些行將與下一張表匹配或者是返回給用戶。如果不想返回表中的全部行,并且連接類型ALLindex,這就會發(fā)生,或者是查詢有問題不同連接類型的解釋;

四、引起索引失效的一些因素

1、  like語句操作

一般情況下不鼓勵使用like操作,如果非使用不可,如何使用也是一個問題。like %aaa%”不會使用索引而like aaa%”可以使用索引。

例如:


2、  在索引列上使用函數(shù),或者對索引列進行運算,運算包括( -,*/,! )會導致索引失效。

例如:


3、  查詢的數(shù)量是表的大部分,應(yīng)該是30%以上。

例如:


4、  字符型字段為數(shù)字時在where條件里不添加引號。

例如:

          被測試數(shù)據(jù)庫的表結(jié)構(gòu)如下:


這是添加了引號的sql語句的執(zhí)行計劃:


這是沒有添加引號的sql語句的執(zhí)行計劃:


    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多