你知道數(shù)據(jù)庫索引的工作原理嗎?
問:隨著數(shù)據(jù)庫的增大,既然索引的作用那么重要,有誰能拋開具體的數(shù)據(jù)庫來解釋一下索引的工作原理?
答:
什么是索引
索引的原理
首先,來看一個示例數(shù)據(jù)庫表的模式:
字段名??????????????數(shù)據(jù)類型?????????在磁盤上的大小
id?(Primary?key)???Unsigned?INT?????4?字節(jié)
firstName??????????Char(50)?????????50?字節(jié)
lastName???????????Char(50)?????????50?字節(jié)
emailAddress???????Char(100)????????100?字節(jié)char而不用varchar是為了精確地描述數(shù)據(jù)占用磁盤的大小。這個示例數(shù)據(jù)庫中包含500萬行記錄,而且沒有建立索引。接下來我們就分析針對這個表的兩個查詢:一個查詢使用id(經(jīng)過排序的鍵字段),另一個查詢使用firstName(未經(jīng)排序的非鍵字段)。示例分析一
字段名?????????數(shù)據(jù)類型????????在磁盤上的大小
firstName?????Char(50)????????50?字節(jié)
(記錄指針)????Special?????????4?字節(jié)注意:在MySQL中,根據(jù)表的大小,指針的大小可能是2、3、4或5字節(jié)。
示例分析二
什么時候用索引
創(chuàng)建索引要額外占用磁盤空間(比如,上面例子中要額外占用277 778個數(shù)據(jù)塊),建立的索引太多可能導致磁盤空間不足。因此,在建立索引時,一定要慎重選擇正確的字段。
由于索引只能提高搜索記錄中某個匹配字段的速度,因此在執(zhí)行插入和刪除操作的情況下,僅為輸出結(jié)果而為字段建立索引,就純粹是浪費磁盤空間和處理時間了;這種情況下不用建立索引。另外,由于二分查找的原因,數(shù)據(jù)的基數(shù)性(cardinality)或唯一性也非常重要。對基數(shù)性為2的字段建立索引,會將數(shù)據(jù)一分為二,而對基數(shù)性為1000的字段,則同樣會返回大約1000條記錄。在這么低的基數(shù)性下,索引的效率將減低至線性查找的水平,而查詢優(yōu)化器會在基數(shù)性小于記錄數(shù)的30%時放棄索引,實際上等于索引純粹只會浪費空間。
查詢優(yōu)化器的原理:
? ? 查詢優(yōu)化中最核心的問題就是精確估算不同查詢計劃的成本。優(yōu)化器在估算查詢計劃的成本時,會使用一個數(shù)學模型,該模型又依賴于對每個查詢計劃中涉及的最大數(shù)據(jù)量的基數(shù)性(或者叫重數(shù))的估算。而對基數(shù)性的估算又依賴于對查詢中謂詞選擇因數(shù)(selection factor of predicates)的估算。過去,數(shù)據(jù)庫系統(tǒng)在估算選擇性時,要使用每個字段中值的分布情況的詳盡統(tǒng)計信息,比如直方圖。這種技術(shù)對于估算孤立謂詞的選擇符效果很好。然而,很多查詢的謂詞是相互關(guān)聯(lián)的,例如select count(*) from R where R.make='Honda' and R.model='Accord'。查詢謂詞經(jīng)常會高度關(guān)聯(lián)(比如,model='Accord'的前提條件是make='Honda'),而估計這種關(guān)聯(lián)的選擇性非常困難。查詢優(yōu)化器之所以會選擇低劣的查詢計劃,一方面是因為對基數(shù)性估算不準,另一方面就是因為遺漏了很多關(guān)聯(lián)性。而這也是為什么數(shù)據(jù)庫管理員應該經(jīng)常更新數(shù)據(jù)庫統(tǒng)計信息(特別是在重要的數(shù)據(jù)加載和卸載之后)的原因。
最后
如果這篇文章對您有所幫助,或者有所啟發(fā)的話,幫忙掃描下發(fā)二維碼關(guān)注一下,您的支持是我堅持寫作最大的動力。求一鍵三連:點贊、轉(zhuǎn)發(fā)、在看
