-
當前位置:首頁 > 創(chuàng)意學院 > 技術(shù) > 專題列表 > 正文
索引加快查詢的原理(索引的作用之一是加快查詢速度)
大家好!今天讓創(chuàng)意嶺的小編來大家介紹下關(guān)于索引加快查詢的原理的問題,以下是小編對此問題的歸納整理,讓我們一起來看看吧。
開始之前先推薦一個非常厲害的Ai人工智能工具,一鍵生成原創(chuàng)文章、方案、文案、工作計劃、工作報告、論文、代碼、作文、做題和對話答疑等等
只需要輸入關(guān)鍵詞,就能返回你想要的內(nèi)容,越精準,寫出的就越詳細,有微信小程序端、在線網(wǎng)頁版、PC客戶端
官網(wǎng):https://ai.de1919.com。
創(chuàng)意嶺作為行業(yè)內(nèi)優(yōu)秀的企業(yè),服務客戶遍布全球各地,如需了解SEO相關(guān)業(yè)務請撥打電話175-8598-2043,或添加微信:1454722008
本文目錄:
一、數(shù)據(jù)庫索引原理
數(shù)據(jù)庫索引原理如下:
使用索引可快速訪問數(shù)據(jù)庫表中的特定信息。如果想按特定職員的姓來查找人員,則與在表中搜索所有的行相比,索引有助于更快地獲取信息。
索引的實現(xiàn)通常使用B樹及其變種B+樹。在數(shù)據(jù)之外,數(shù)據(jù)庫系統(tǒng)還維護著滿足特定查找算法的數(shù)據(jù)結(jié)構(gòu),這些數(shù)據(jù)結(jié)構(gòu)以某種方式引用(指向)數(shù)據(jù),這樣就可以在這些數(shù)據(jù)結(jié)構(gòu)上實現(xiàn)高級查找算法。
擴展資料:
對于有些列不應該創(chuàng)建索引。一般來說,不應該創(chuàng)建索引的的這些列具有下列特點:
1、查詢很少:
對于那些在查詢中很少使用或者參考的列不應該創(chuàng)建索引。這是因為,既然這些列很少使用到,因此有索引或者無索引,并不能提高查詢速度。相反,由于增加了索引,反而降低了系統(tǒng)的維護速度和增大了空間需求。
2、少數(shù)據(jù)值:
對于那些只有很少數(shù)據(jù)值的列也不應該增加索引。這是因為,由于這些列的取值很少,例如人事表的性別列,在查詢的結(jié)果中,結(jié)果集的數(shù)據(jù)行占了表中數(shù)據(jù)行的很大比例,即需要在表中搜索的數(shù)據(jù)行的比例很大。增加索引,并不能明顯加快檢索速度。
3、定義類型:
對于那些定義為text, image和bit數(shù)據(jù)類型的列不應該增加索引。這是因為,這些列的數(shù)據(jù)量要么相當大,要么取值很少。
參考資料來源:百度百科——數(shù)據(jù)庫索引
二、mysql索引為什么可以提升查詢性能
索引對查詢的速度有著至關(guān)重要的影響,理解索引也是進行數(shù)據(jù)庫性能調(diào)優(yōu)的起點??紤]如下情況,假設(shè)數(shù)據(jù)庫中一個表有10^6條記錄,DBMS的頁面大小為4K,并存儲100條記錄。如果沒有索引,查詢將對整個表進行掃描,最壞的情況下,如果所有數(shù)據(jù)頁都不在內(nèi)存,需要讀取10^4個頁面,如果這10^4個頁面在磁盤上隨機分布,需要進行10^4次I/O,假設(shè)磁盤每次I/O時間為10ms(忽略數(shù)據(jù)傳輸時間),則總共需要100s(但實際上要好很多很多)。如果對之建立B-Tree索引,則只需要進行l(wèi)og100(10^6)=3次頁面讀取,最壞情況下耗時30ms。這就是索引帶來的效果,很多時候,當你的應用程序進行SQL查詢速度很慢時,應該想想是否可以建索引。
摘自http://www.cnblogs.com/hustcat/archive/2009/10/28/1591648.html
三、為什么索引會快,請高手告訴我索引的原理是什么?
通俗來講就是一個快速智能排除與組合的原理,當你打出一個,它會快速搜索這個字的相關(guān)組成,打的字越多精確
四、如何寫索引,讓查詢速度快
首先來看看表是否有索引的命令
show index from 表名;
看到主鍵索引,索引類型是BTREE(二叉樹)
正是因為這個二叉樹算法,讓查詢速度快很多,二叉樹的原理,就是取最中間的一個數(shù),然后把大于這個數(shù)的往右邊排,小于這個數(shù)的就向左排,每次減半,然后依次類推,每次減半,形成一個樹狀結(jié)構(gòu)圖
例如上面的例子,我們不使用索引的話,需要查詢11次才把編號為4的數(shù)據(jù)取出,如果加上索引,我們只需要4次就可以取出。
如大家所知道的,MySQL目前主要有以下幾種索引類型:FULLTEXT,HASH,BTREE,RTREE。
那么,這幾種索引有什么功能和性能上的不同呢?
FULLTEXT
即為全文索引,目前只有MyISAM引擎支持。其可以在CREATE TABLE ,ALTER TABLE ,CREATE INDEX 使用,不過目前只有 CHAR、VARCHAR ,TEXT 列上可以創(chuàng)建全文索引。值得一提的是,在數(shù)據(jù)量較大時候,現(xiàn)將數(shù)據(jù)放入一個沒有全局索引的表中,然后再用CREATE INDEX創(chuàng)建FULLTEXT索引,要比先為一張表建立FULLTEXT然后再將數(shù)據(jù)寫入的速度快很多。
全文索引并不是和MyISAM一起誕生的,它的出現(xiàn)是為了解決WHERE name LIKE “%word%"這類針對文本的模糊查詢效率較低的問題。在沒有全文索引之前,這樣一個查詢語句是要進行遍歷數(shù)據(jù)表操作的,可見,在數(shù)據(jù)量較大時是極其的耗時的,如果沒有異步IO處理,進程將被挾持,很浪費時間,當然這里不對異步IO作進一步講解,想了解的童鞋,自行谷哥。
全文索引的使用方法并不復雜:
創(chuàng)建ALTER TABLE table ADD INDEX `FULLINDEX` USING FULLTEXT(`cname1`[,cname2…]);
使用SELECT * FROM table WHERE MATCH(cname1[,cname2…]) AGAINST ('word' MODE );
其中, MODE為搜尋方式(IN BOOLEAN MODE ,IN NATURAL LANGUAGE MODE ,IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION / WITH QUERY EXPANSION)。
關(guān)于這三種搜尋方式,愚安在這里也不多做交代,簡單地說,就是,布爾模式,允許word里含一些特殊字符用于標記一些具體的要求,如+表示一定要有,-表示一定沒有,*表示通用匹配符,是不是想起了正則,類似吧;自然語言模式,就是簡單的單詞匹配;含表達式的自然語言模式,就是先用自然語言模式處理,對返回的結(jié)果,再進行表達式匹配。
對搜索引擎稍微有點了解的同學,肯定知道分詞這個概念,F(xiàn)ULLTEXT索引也是按照分詞原理建立索引的。西文中,大部分為字母文字,分詞可以很方便的按照空格進行分割。但很明顯,中文不能按照這種方式進行分詞。那又怎么辦呢?這個向大家介紹一個Mysql的中文分詞插件Mysqlcft,有了它,就可以對中文進行分詞,想了解的同學請移步Mysqlcft,當然還有其他的分詞插件可以使用。
HASH
Hash這個詞,可以說,自打我們開始碼的那一天起,就開始不停地見到和使用到了。其實,hash就是一種(key=>value)形式的鍵值對,如數(shù)學中的函數(shù)映射,允許多個key對應相同的value,但不允許一個key對應多個value。正是由于這個特性,hash很適合做索引,為某一列或幾列建立hash索引,就會利用這一列或幾列的值通過一定的算法計算出一個hash值,對應一行或幾行數(shù)據(jù)(這里在概念上和函數(shù)映射有區(qū)別,不要混淆)。在Java語言中,每個類都有自己的hashcode()方法,沒有顯示定義的都繼承自object類,該方法使得每一個對象都是唯一的,在進行對象間equal比較,和序列化傳輸中起到了很重要的作用。hash的生成方法有很多種,足可以保證hash碼的唯一性,例如在MongoDB中,每一個document都有系統(tǒng)為其生成的唯一的objectID(包含時間戳,主機散列值,進程PID,和自增ID)也是一種hash的表現(xiàn)。額,我好像扯遠了-_-!
由于hash索引可以一次定位,不需要像樹形索引那樣逐層查找,因此具有極高的效率。那為什么還需要其他的樹形索引呢?
在這里愚安就不自己總結(jié)了。引用下園子里其他大神的文章:來自 14的路 的MySQL的btree索引和hash索引的區(qū)別
(1)Hash 索引僅僅能滿足"=","IN"和"<=>"查詢,不能使用范圍查詢。
由于 Hash 索引比較的是進行 Hash 運算之后的 Hash 值,所以它只能用于等值的過濾,不能用于基于范圍的過濾,因為經(jīng)過相應的 Hash 算法處理之后的 Hash 值的大小關(guān)系,并不能保證和Hash運算前完全一樣。
(2)Hash 索引無法被用來避免數(shù)據(jù)的排序操作。
由于 Hash 索引中存放的是經(jīng)過 Hash 計算之后的 Hash 值,而且Hash值的大小關(guān)系并不一定和 Hash 運算前的鍵值完全一樣,所以數(shù)據(jù)庫無法利用索引的數(shù)據(jù)來避免任何排序運算;
(3)Hash 索引不能利用部分索引鍵查詢。
對于組合索引,Hash 索引在計算 Hash 值的時候是組合索引鍵合并后再一起計算 Hash 值,而不是單獨計算 Hash 值,所以通過組合索引的前面一個或幾個索引鍵進行查詢的時候,Hash 索引也無法被利用。
(4)Hash 索引在任何時候都不能避免表掃描。
前面已經(jīng)知道,Hash 索引是將索引鍵通過 Hash 運算之后,將 Hash運算結(jié)果的 Hash 值和所對應的行指針信息存放于一個 Hash 表中,由于不同索引鍵存在相同 Hash 值,所以即使取滿足某個 Hash 鍵值的數(shù)據(jù)的記錄條數(shù),也無法從 Hash 索引中直接完成查詢,還是要通過訪問表中的實際數(shù)據(jù)進行相應的比較,并得到相應的結(jié)果。
(5)Hash 索引遇到大量Hash值相等的情況后性能并不一定就會比B-Tree索引高。
對于選擇性比較低的索引鍵,如果創(chuàng)建 Hash 索引,那么將會存在大量記錄指針信息存于同一個 Hash 值相關(guān)聯(lián)。這樣要定位某一條記錄時就會非常麻煩,會浪費多次表數(shù)據(jù)的訪問,而造成整體性能低下。
愚安我稍作補充,講一下HASH索引的過程,順便解釋下上面的第4,5條:
當我們?yōu)槟骋涣谢蚰硯琢薪ash索引時(目前就只有MEMORY引擎顯式地支持這種索引),會在硬盤上生成類似如下的文件:
hash值 存儲地址
1db54bc745a1 77#45b5
4bca452157d4 76#4556,77#45cc…
…
hash值即為通過特定算法由指定列數(shù)據(jù)計算出來,磁盤地址即為所在數(shù)據(jù)行存儲在硬盤上的地址(也有可能是其他存儲地址,其實MEMORY會將hash表導入內(nèi)存)。
這樣,當我們進行WHERE age = 18 時,會將18通過相同的算法計算出一個hash值==>在hash表中找到對應的儲存地址==>根據(jù)存儲地址取得數(shù)據(jù)。
所以,每次查詢時都要遍歷hash表,直到找到對應的hash值,如(4),數(shù)據(jù)量大了之后,hash表也會變得龐大起來,性能下降,遍歷耗時增加,如(5)。
BTREE
BTREE索引就是一種將索引值按一定的算法,存入一個樹形的數(shù)據(jù)結(jié)構(gòu)中,相信學過數(shù)據(jù)結(jié)構(gòu)的童鞋都對當初學習二叉樹這種數(shù)據(jù)結(jié)構(gòu)的經(jīng)歷記憶猶新,反正愚安我當時為了軟考可是被這玩意兒好好地折騰了一番,不過那次考試好像沒怎么考這個。如二叉樹一樣,每次查詢都是從樹的入口root開始,依次遍歷node,獲取leaf。
BTREE在MyISAM里的形式和Innodb稍有不同
在 Innodb里,有兩種形態(tài):一是primary key形態(tài),其leaf node里存放的是數(shù)據(jù),而且不僅存放了索引鍵的數(shù)據(jù),還存放了其他字段的數(shù)據(jù)。二是secondary index,其leaf node和普通的BTREE差不多,只是還存放了指向主鍵的信息.
而在MyISAM里,主鍵和其他的并沒有太大區(qū)別。不過和Innodb不太一樣的地方是在MyISAM里,leaf node里存放的不是主鍵的信息,而是指向數(shù)據(jù)文件里的對應數(shù)據(jù)行的信息.
RTREE
RTREE在mysql很少使用,僅支持geometry數(shù)據(jù)類型,支持該類型的存儲引擎只有MyISAM、BDb、InnoDb、NDb、Archive幾種。
相對于BTREE,RTREE的優(yōu)勢在于范圍查找.
各種索引的使用情況
(1)對于BTREE這種Mysql默認的索引類型,具有普遍的適用性
(2)由于FULLTEXT對中文支持不是很好,在沒有插件的情況下,最好不要使用。其實,一些小的博客應用,只需要在數(shù)據(jù)采集時,為其建立關(guān)鍵字列表,通過關(guān)鍵字索引,也是一個不錯的方法,至少愚安我是經(jīng)常這么做的。
(3)對于一些搜索引擎級別的應用來說,F(xiàn)ULLTEXT同樣不是一個好的處理方法,Mysql的全文索引建立的文件還是比較大的,而且效率不是很高,即便是使用了中文分詞插件,對中文分詞支持也只是一般。真要碰到這種問題,Apache的Lucene或許是你的選擇。
(4)正是因為hash表在處理較小數(shù)據(jù)量時具有無可比擬的素的優(yōu)勢,所以hash索引很適合做緩存(內(nèi)存數(shù)據(jù)庫)。如mysql數(shù)據(jù)庫的內(nèi)存版本Memsql,使用量很廣泛的緩存工具Mencached,NoSql數(shù)據(jù)庫redis等,都使用了hash索引這種形式。當然,不想學習這些東西的話Mysql的MEMORY引擎也是可以滿足這種需求的。
以上就是關(guān)于索引加快查詢的原理相關(guān)問題的回答。希望能幫到你,如有更多相關(guān)問題,您也可以聯(lián)系我們的客服進行咨詢,客服也會為您講解更多精彩的知識和內(nèi)容。
推薦閱讀:
寧波搜索引擎優(yōu)化關(guān)鍵詞(寧波seo搜索排名優(yōu)化)
北京搜索引擎優(yōu)化電話(北京搜索引擎優(yōu)化seo)