|
小編導讀:
在性能測試中遇到性能瓶頸最多的地方就是數(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就可以了:
1、id:SELECT識別符。這是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)該盡量避免。 Explain的type顯示的是訪問類型,是較為重要的一個指標,結(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語句中使用USEINDEX(indexname)來強制使用一個索引或者用IGNORE INDEX(indexname)來強制MYSQL忽略索引。 6、key_len:使用的索引的長度。在不損失精確性的情況下,長度越短越好。 7、ref:顯示索引的哪一列被使用了,如果可能的話,是一個常數(shù)。 8、rows:MYSQL認為必須檢查的用來返回請求數(shù)據(jù)的行數(shù)。 9、Extra:關(guān)于MYSQL如何解析查詢的額外信息。 extra列返回值描述如下:
四、引起索引失效的一些因素 1、 like語句操作 一般情況下不鼓勵使用like操作,如果非使用不可,如何使用也是一個問題。like “%aaa%”不會使用索引而like “aaa%”可以使用索引。 例如:
例如:
例如: 4、 字符型字段為數(shù)字時在where條件里不添加引號。 例如: 被測試數(shù)據(jù)庫的表結(jié)構(gòu)如下:
|
|
|