當前位置:成語大全網 - 古籍善本 - 怎麽寫索引讓查詢更快?

怎麽寫索引讓查詢更快?

首先,讓我們看看這個表是否有壹個索引命令。

從表名顯示索引;

參見主鍵索引,索引類型為BTREE(二叉樹)

正是因為有了這種二叉樹算法,查詢速度快了很多。二叉樹的原理是取中間的數,然後將大於這個數的數向右排,小於這個數的數向左排,每次減半,以此類推,形成樹形結構圖。

比如上面的例子,如果不使用索引,我們需要查詢11次才能取出編號為4的數據。如果加上索引,只需要4次就可以拿出來了。

眾所周知,MySQL目前有以下幾種索引類型:FULLTEXT、HASH、BTREE、RTREE。

那麽,這些指標在功能和性能上有什麽區別呢?

全文

也就是全文索引,目前只有MyISAM引擎支持。可以在CREATE TABLE、ALTER TABLE和CREATE INDEX中使用,但目前只有CHAR、VARCHAR和TEXT列可以創建全文索引。值得壹提的是,當數據量較大時,將數據放入壹個沒有全局索引的表中,然後用CREATE INDEX創建全文索引,比先為壹個表創建全文,然後再寫入數據要快得多。

全文索引並不是伴隨著MyISAM誕生的,而是為了解決諸如Where Name Like“% word %”等文本的模糊查詢效率低的問題而出現的。在沒有全文索引之前,這樣的查詢語句需要遍歷數據表。可見在數據量較大的情況下是極其耗時的。如果沒有異步IO處理,進程就會被劫持,浪費時間。當然,異步IO在這裏就不做進壹步解釋了。想了解童鞋,請去谷歌。

全文索引的使用並不復雜:

create alter table table add index ` full index ` using full text(` cname 1 `[,cname 2…]);

對(' word '模式)使用select * from table where match(cname 1[,cname 2…]);

其中,MODE是搜索模式(在布爾模式下,在帶有查詢擴展的自然語言模式下/帶有查詢擴展)。

關於這三種搜索方式,裕安在此不做過多解釋。簡單來說就是布爾模式,允許word包含壹些特殊字符來標記壹些特定的需求,比如+表示壹定有,-表示壹定沒有,*表示有通用匹配器。是否讓人想起規律和相似?自然語言模式是簡單的單詞匹配;帶表達式的自然語言模式是指首先使用自然語言模式,然後將返回的結果與表達式進行匹配。

對搜索引擎稍有了解的同學壹定知道分詞的概念,全文索引也是基於分詞的原理。在西方語言中,大部分是字母字符,分詞很容易按照空格來劃分。但很明顯,中文不能這樣切分。那我該怎麽辦呢?這是為您介紹壹個中文分詞插件Mysql CFT。有了它,妳可以切分中文單詞。想了解的同學請去Mysqlcft。當然還有其他的分詞插件可以用。

混雜

可以說,從我們開始編碼的那壹天起,Hash這個詞就被不斷地看到和使用。實際上,哈希是壹種(key = & gtValue),如數學中的函數映射,允許多個鍵對應同壹個值,但不允許壹個鍵對應多個值。正是因為這個特性,hash非常適合做索引。如果為某壹列或幾列建立了散列索引,就會利用這壹列或幾列的值通過壹定的算法計算出壹個散列值,對應壹行或幾行數據(這裏和函數映射概念上不同,不要混淆)。在Java語言中,每個類都有自己的hashcode()方法,所有沒有顯示定義的都是從object類繼承的。這種方法使每個對象都是唯壹的,在對象之間的平等比較和序列化傳輸中起著重要作用。哈希有多種生成方式,可以保證哈希代碼的唯壹性。比如在MongoDB中,每個文檔都有壹個系統生成的唯壹objectID(包括時間戳、主機哈希值、進程PID、自增ID),這也是hash的壹種表示。嗯,我好像跑題了-_-!

因為哈希索引可以壹次定位,不需要像樹索引那樣逐層查找,所以效率高。那為什麽還需要其他樹索引呢?

這裏於安就不自己總結了。引用園內其他大神的文章:從14之路看MySQL的btree索引和hash索引的區別。

(1)哈希索引只能滿足“=”、“IN”和“< = >查詢,不能使用範圍查詢。

因為哈希索引比較的是哈希運算後的哈希值,所以只能用於等價過濾,不能用於基於範圍的過濾,因為相應哈希算法處理後的哈希值大小關系不能保證和哈希運算前完全壹樣。

(2)哈希索引不能用來避免對數據進行排序。

由於哈希索引中存儲的哈希值是哈希計算後的哈希值,而哈希值的大小關系與哈希運算前的鍵值不壹定相同,所以數據庫無法使用索引數據來避免任何排序操作;

(3)哈希索引不能通過部分索引鍵查詢。

對於組合索引,哈希索引在組合索引鍵合並後壹起計算哈希值,而不是單獨計算哈希值,因此在通過第壹個索引鍵或組合索引的鍵進行查詢時不能使用哈希索引。

(4)哈希索引無法隨時避免表掃描。

我們之前已經知道,哈希索引是將哈希運算結果的哈希值和對應的行指針信息在索引鍵哈希後存儲在壹個哈希表中。由於不同的索引鍵具有相同的hash值,所以即使取滿足某個Hash鍵值的數據的記錄數,也不能直接從Hash索引完成查詢,而是通過訪問表中的實際數據得到相應的結果。

(5)在大量哈希值相等的情況下,哈希索引的性能不壹定比B樹索引高。

對於低選擇性的索引鍵,如果創建散列索引,將會有大量的記錄指針信息與同壹個散列值相關聯。這樣定位某條記錄會很麻煩,會浪費很多對表數據的訪問,造成整體性能低下。

我再做壹點補充,告訴妳HASH索引的過程,順便解釋壹下上面的第4項和第5項:

當我們為壹列或多列創建散列索引時(目前只有內存引擎明確支持該索引),硬盤上將生成壹個類似於以下內容的文件:

哈希值存儲地址

1db 54 BC 745 a 1 77 # 45 b5

4bca452157d4 76#4556,77#45cc…

哈希值是通過特定的算法從指定的列數據中計算出來的,磁盤地址是數據行在硬盤上存儲的地址(也可能是其他存儲地址,實際上內存會將哈希表導入內存)。

這樣我們在進行WHERE age = 18的時候,通過同樣的算法會計算出壹個18的hash值= = >;在哈希表中找到對應的存儲地址= = & gt根據存儲地址獲取數據。

因此,每個查詢都必須遍歷哈希表,直到找到對應的哈希值,比如(4)。數據量大了之後,哈希表也會變得巨大,性能下降,遍歷時間增加,比如(5)。

BTREE

BTREE索引是將索引值按照壹定的算法存儲在樹中的壹種數據結構。相信學過數據結構的童鞋還記得當初學習二叉樹數據結構的經歷。反正我為了軟考被這個東西折騰的夠嗆,不過那次好像沒考這個。像二叉樹壹樣,每個查詢都從樹的入口根開始,依次遍歷節點,獲得葉子。

MyISAM中BTREE的形式與Innodb略有不同。

在Innodb中,有兩種形式:壹種是主鍵形式,葉子節點存儲數據,不僅有索引鍵的數據,還有其他字段的數據。第二個是secondary index,它的葉節點類似於普通的BTREE,但也存儲指向主鍵的信息。

在MyISAM中,主鍵和其他的沒有太大區別。但與Innodb不同的是,在MyISAM中,葉子節點存儲的信息不是主鍵,而是指向數據文件中相應數據行的信息。

RTREE

RTREE在mysql中很少使用,只支持geometry數據類型。只有幾個存儲引擎支持這種類型:MyISAM、BDb、InnoDb、NDb和Archive。

與BTREE相比,RTREE具有範圍搜索的優勢。

各種索引的使用

(1)對BTREE具有普遍適用性,BTREE是Mysql的默認索引類型。

(2)因為FULLTEXT不太支持中文,所以沒有插件最好不要用。其實壹些小的博客應用在收集數據的時候只需要為他們建立壹個關鍵詞列表,通過關鍵詞對他們進行索引也是壹個不錯的方法,至少我經常這麽做。

(3)對於壹些搜索引擎級別的應用,全文也不是壹個好的處理方法。Mysql的全文索引創建的文件還是比較大的,效率不是很高。即使使用中文分詞插件,對中文分詞的支持也只是壹般。如果真的遇到這種問題,Apache的Lucene可能是妳的選擇。

(4)哈希索引非常適合緩存(內存數據庫),因為它在處理小數據時具有不可比擬的素數優勢。比如mysql數據庫的內存版Memsql,廣泛使用的緩存工具Mencached,NoSql數據庫redis,都是使用這種形式的哈希索引。當然,如果妳不想學這些東西,Mysql的內存引擎也可以滿足這個需求。