為什么索引可以提高效率?
對於索引的應用比較常見,索引的底層數據結構也有一定的了解,但是一直在思考為什么索引會提高效率,后來,參考網上的文章,終於得到解釋。
============================================================
本文只針對mysql進行相關方面的說明。
首先我要問,“數據索引是有序無序的?”。答:“當然是有序的了。”
再問,一個SQL語句可以有幾個索引?你先別往下看結果,你這想下,可以使用幾個索引呢?正確的是:“1個”。有人肯定會疑惑。對,當初我接受這個概念也是挺納悶的,后來在實際中得到了解答。那么,你需自己找答案了。
在有序的情況下,通過索引查詢一個數據是無需遍歷索引記錄的;
極端情況下,數據索引的查詢效率為二分法查詢效率,趨近於 log2(N);
在進行索引分析和SQL優化時,可以將數據索引字段想象為單一有序序列,並以此作為分析的基礎。
如以下的SQL,如何進行優化呢?
1
|
select
*
from
user
where
area=’$area’
and
sex=’$sex’
order
by
lastlogin
desc
limit 0,30;
|
假設,這是在高訪問量的情況下,高頻率的情況下如何進行優化?答:建立復合索引.
area+sex+lastlogin 三個字段的復合索引,如何理解?
1 如果只使用area會怎樣?搜索會把符合area的結果全部找出來,然后在這里面遍歷,選擇命中sex的並排序。 遍歷所有 area=’$area’數據。
2 如果使用了area+sex,略好,仍然要遍歷所有area=’$area’ and sex=’$sex’數據,然后在這個基礎上排序。
3 Area+sex+lastlogin復合索引時(切記lastlogin在最后),該索引基於area+sex+lastlogin 三個字段合並的結果排序。
不知道到這你是否看明白沒有??這個不妨你在本地打個環境。自己動手試試看。
下面我用我自己的工作中的案例說下,這索引前后的區別:
我們有個業務需求是這樣的:
SELECT
*
FROM
`cu_banuser`
WHERE
uid =386264
AND
fid =2
ORDER
BY
`endtime`
|
1 這是一張表結構 如圖。此表只有一個主鍵作為索引。
那么我們用explain看下吧: 關於explain,強烈建議:請大家自己baidu,有必要去了解認識它。
EXPLAIN
SELECT
*
FROM
`cu_banuser`
WHERE
uid =386264
AND
fid =2
ORDER
BY
`endtime`
|
下面的是其explain的結果:
看到其中的 type possible_keys 尤其是rows了嗎?影響的結果集是2751行。
2 我們現在將UID做為索引:
再explain下:
看划線的,你們會驚喜的發現 rows已經是2了。證明我們的努力沒有白費。
3 我們繼續添加剩下的索引fid;
好,我們再explain下,看結果:
你會發現什么呢?呵呵,對了 rows=1了。
4 繼續給endtime加索引
explain看下:
我們的rows=1了,很明顯的如果在大數據量的情況下,我們的獲得的成果是很可喜的!我們一切從大數量出發。
好,不知道你注意到開篇就提到的2個問題吧?第二個問題是什么?一個sql用幾個索引?答案是1個。
看到這,不知道你有沒有感悟出來呢?我們在實際工作中用到最多的就是復合索引!
這就是你為什么看到上圖的框中的索引是這么建的!
補充下 從最好到最差的連接類型為 :const、eq_reg、ref、range、index和ALL
綜上所述:
1 一個sql只用一個索引;
2在實際工作中用到最多的是復合索引;
3 復合索引有嚴格的順序之分;
4 遵循偏左原則;