2019-05-10單表索引類型

const

????通過主鍵列來定位一條記錄?例如:SELECT * FROM single_table WHERE id = 1438;

ref

? ??某個普通的二級索引列與常數(shù)進行等值比較??SELECT * FROM single_table WHERE key1 = 'abc';

ref_or_null

????找出某個二級索引列的值等于某個常數(shù)的記錄楞抡,還想把該列的值為NULL的記錄也找出來

? ??SELECT * FROM single_demo WHERE key1 = 'abc' OR key1 IS NULL;

range

????利用索引進行范圍匹配的訪問方法稱之為:range

????SELECT * FROM single_table WHERE key2 IN (1438, 6328) OR (key2 >= 38 AND key2 <= 79);

index????

? ? 聯(lián)合索引?查詢第一個字段時?使用index

? ??SELECT key_part1, key_part2, key_part3 FROM single_table WHERE key_part2 = 'abc';

all?

? ??最直接的查詢執(zhí)行方式就是我們已經(jīng)提了無數(shù)遍的全表掃描,對于InnoDB表來說也就是直接掃描聚簇索引纳像,設計MySQL的大叔把這種使用全表掃描執(zhí)行查詢的方式稱之為:all


二級索引 + 回表

一般情況下只能利用單個二級索引執(zhí)行查詢果覆,比方說下邊的這個查詢:

SELECT * FROM single_table WHERE key1 ='abc'AND key2 > 1000;

查詢優(yōu)化器會識別到這個查詢中的兩個搜索條件:

key1 = 'abc'

key2 > 1000

優(yōu)化器一般會根據(jù)single_table表的統(tǒng)計數(shù)據(jù)來判斷到底使用哪個條件到對應的二級索引中查詢掃描的行數(shù)會更少辐烂,選擇那個掃描行數(shù)較少的條件到對應的二級索引中查詢(關于如何比較的細節(jié)我們后邊的章節(jié)中會嘮叨)。然后將從該二級索引中查詢到的結果經(jīng)過回表得到完整的用戶記錄后再根據(jù)其余的WHERE條件過濾記錄拯爽。一般來說最蕾,等值查找比范圍查找需要掃描的行數(shù)更少(也就是ref的訪問方法一般比range好炕横,但這也不總是一定的源内,也可能采用ref訪問方法的那個索引列的值為特定值的行數(shù)特別多),所以這里假設優(yōu)化器決定使用idx_key1索引進行查詢份殿,那么整個查詢過程可以分為兩個步驟:

步驟1:使用二級索引定位記錄的階段膜钓,也就是根據(jù)條件key1 = 'abc'從idx_key1索引代表的B+樹中找到對應的二級索引記錄。

步驟2:回表階段卿嘲,也就是根據(jù)上一步驟中找到的記錄的主鍵值進行回表操作颂斜,也就是到聚簇索引中找到對應的完整的用戶記錄,再根據(jù)條件key2 > 1000到完整的用戶記錄繼續(xù)過濾拾枣。將最終符合過濾條件的記錄返回給用戶沃疮。

這里需要特別提醒大家的一點是,因為二級索引的節(jié)點中的記錄只包含索引列和主鍵梅肤,所以在步驟1中使用idx_key1索引進行查詢時只會用到與key1列有關的搜索條件司蔬,其余條件,比如key2 > 1000這個條件在步驟1中是用不到的凭语,只有在步驟2完成回表操作后才能繼續(xù)針對完整的用戶記錄中繼續(xù)過濾葱她。

明確range訪問方法使用的范圍區(qū)間

其實對于B+樹索引來說,只要索引列和常數(shù)使用=似扔、<=>、IN搓谆、NOT IN炒辉、IS NULL、IS NOT NULL泉手、>黔寇、<、>=斩萌、<=缝裤、BETWEEN屏轰、!=(不等于也可以寫成<>)或者LIKE操作符連接起來,就可以產生一個所謂的區(qū)間憋飞。

小貼士: LIKE操作符比較特殊霎苗,只有在匹配完整字符串或者匹配字符串前綴時才可以利用索引,具體原因我們在前邊的章節(jié)中嘮叨過了榛做,這里就不贅述了唁盏。 IN操作符的效果和若干個等值匹配操作符`=`之間用`OR`連接起來是一樣的,也就是說會產生多個單點區(qū)間检眯,比如下邊這兩個語句的效果是一樣的: SELECT * FROM single_table WHERE key2 IN (1438, 6328); SELECT * FROM single_table WHERE key2 = 1438 OR key2 = 6328;

不過在日常的工作中厘擂,一個查詢的WHERE子句可能有很多個小的搜索條件,這些搜索條件需要使用AND或者OR操作符連接起來

索引合并

我們前邊說過MySQL在一般情況下執(zhí)行一個查詢時最多只會用到單個二級索引锰瘸,但不是還有特殊情況么刽严,在這些特殊情況下也可能在一個查詢中使用到多個二級索引,設計MySQL的大叔把這種使用到多個索引來完成一次查詢的執(zhí)行方法稱之為:index merge避凝,具體的索引合并算法有下邊三種舞萄。

Intersection合并

Intersection翻譯過來的意思是交集。這里是說某個查詢可以使用多個二級索引恕曲,將從多個二級索引中查詢到的結果取交集鹏氧,比方說下邊這個查詢:

SELECT * FROM single_table WHERE key1 ='a'AND key3 ='b';

假設這個查詢使用Intersection合并的方式執(zhí)行的話,那這個過程就是這樣的:

從idx_key1二級索引對應的B+樹中取出key1 = 'a'的相關記錄佩谣。

從idx_key3二級索引對應的B+樹中取出key3 = 'b'的相關記錄把还。

二級索引的記錄都是由索引列 + 主鍵構成的,所以我們可以計算出這兩個結果集中id值的交集茸俭。

按照上一步生成的id值列表進行回表操作吊履,也就是從聚簇索引中把指定id值的完整用戶記錄取出來,返回給用戶调鬓。

這里有同學會思考:為啥不直接使用idx_key1或者idx_key3只根據(jù)某個搜索條件去讀取一個二級索引艇炎,然后回表后再過濾另外一個搜索條件呢?這里要分析一下兩種查詢執(zhí)行方式之間需要的成本代價腾窝。

只讀取一個二級索引的成本:

按照某個搜索條件讀取一個二級索引

根據(jù)從該二級索引得到的主鍵值進行回表操作缀踪,然后再過濾其他的搜索條件

讀取多個二級索引之后取交集成本:

按照不同的搜索條件分別讀取不同的二級索引

將從多個二級索引得到的主鍵值取交集,然后進行回表操作

雖然讀取多個二級索引比讀取一個二級索引消耗性能虹脯,但是讀取二級索引的操作是順序I/O驴娃,而回表操作是隨機I/O抄课,所以如果只讀取一個二級索引時需要回表的記錄數(shù)特別多扮休,而讀取多個二級索引之后取交集的記錄數(shù)非常少,當節(jié)省的因為回表而造成的性能損耗比訪問多個二級索引帶來的性能損耗更高時启昧,讀取多個二級索引后取交集比只讀取一個二級索引的成本更低。

Union合并

我們在寫查詢語句時經(jīng)常想把既符合某個搜索條件的記錄取出來疆柔,也把符合另外的某個搜索條件的記錄取出來咒精,我們說這些不同的搜索條件之間是OR關系。有時候OR關系的不同搜索條件會使用到不同的索引旷档,比方說這樣:

SELECT * FROM single_table WHERE key1 ='a'OR key3 ='b'

Intersection是交集的意思模叙,這適用于使用不同索引的搜索條件之間使用AND連接起來的情況;Union是并集的意思彬犯,適用于使用不同索引的搜索條件之間使用OR連接起來的情況向楼。與Intersection索引合并類似,MySQL在某些特定的情況下才可能會使用到Union索引合并:

情況一:二級索引列是等值匹配的情況谐区,對于聯(lián)合索引來說湖蜕,在聯(lián)合索引中的每個列都必須等值匹配,不能出現(xiàn)只出現(xiàn)匹配部分列的情況宋列。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末昭抒,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子炼杖,更是在濱河造成了極大的恐慌灭返,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件坤邪,死亡現(xiàn)場離奇詭異熙含,居然都是意外死亡,警方通過查閱死者的電腦和手機艇纺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門怎静,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人黔衡,你說我怎么就攤上這事蚓聘。” “怎么了盟劫?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵夜牡,是天一觀的道長。 經(jīng)常有香客問我侣签,道長塘装,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任影所,我火速辦了婚禮氢哮,結果婚禮上,老公的妹妹穿的比我還像新娘型檀。我一直安慰自己,他們只是感情好听盖,可當我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布胀溺。 她就那樣靜靜地躺著裂七,像睡著了一般。 火紅的嫁衣襯著肌膚如雪仓坞。 梳的紋絲不亂的頭發(fā)上背零,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天,我揣著相機與錄音无埃,去河邊找鬼徙瓶。 笑死,一個胖子當著我的面吹牛嫉称,可吹牛的內容都是我干的侦镇。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼织阅,長吁一口氣:“原來是場噩夢啊……” “哼壳繁!你這毒婦竟也來了?” 一聲冷哼從身側響起荔棉,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤闹炉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后润樱,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體渣触,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年壹若,在試婚紗的時候發(fā)現(xiàn)自己被綠了嗅钻。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡舌稀,死狀恐怖啊犬,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情壁查,我是刑警寧澤觉至,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站睡腿,受9級特大地震影響语御,放射性物質發(fā)生泄漏。R本人自食惡果不足惜席怪,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一应闯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧挂捻,春花似錦碉纺、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽耿导。三九已至,卻和暖如春态贤,著一層夾襖步出監(jiān)牢的瞬間舱呻,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工悠汽, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留箱吕,地道東北人。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓柿冲,卻偏偏與公主長得像茬高,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子姻采,可洞房花燭夜當晚...
    茶點故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內容

  • 1 標量子查詢雅采、行子查詢的執(zhí)行方式 我們經(jīng)常在下邊兩個場景中使用到標量子查詢或者行子查詢: SELECT子句中,我...
    括兒之家閱讀 368評論 0 0
  • 這篇文章主要涉及到MySQL的知識點: 索引(包括分類及優(yōu)化方式慨亲,失效條件婚瓜,底層結構) sql語法(join,un...
    一根薯條閱讀 2,724評論 0 8
  • 索引總結 ?????????????????????????????????--Kane 1. 索引 ??每個In...
    未名枯草閱讀 1,076評論 0 1
  • 2018年10月9日刑棵,星期二巴刻,晴。 一直淅淅瀝瀝的下雨蛉签,今天終于晴了一回胡陪,黃黃的太陽懸掛在碧藍的天空中,真...
    秀子_9e99閱讀 181評論 0 0
  • 陽光隔著那么遠的天空碍舍,穿過云層柠座,跨過馬路,從窗戶探出微笑的臉片橡,溫暖的照在屋里的白墻上妈经,看的見的陽光明媚著心里的每個...
    四葉草工作室2008閱讀 444評論 1 2