[数据库基础]——索引详解
閱讀導航
提高性能
索引
??? B-tree 索引
??? Hash 索引
??? 其他類型
指針
索引百利無一害
?
?
索引對于接觸過數(shù)據(jù)庫的人,都不會很陌生,但是說實話,也不一定很熟悉。先來介紹下索引的優(yōu)點。
?
提高性能
現(xiàn)在有一個數(shù)據(jù)庫表[Words],有[WordID],[WordPage],[[WordName],[WordPronunciation] ,[WordMeaning],[WordSentence]五個列,假設(shè)有上萬條記錄。
現(xiàn)在,使用查詢語句找到“boyce”的詳細信息,使用語句
1: SELECT * FROM [Words] 2: WHERE [WordName] = 'boyce'?
執(zhí)行這個語句會發(fā)生什么?實際上程序在后臺找一個單詞“boyce”。數(shù)據(jù)庫可能會查找表的每一行,是否存在一個單詞“boyce”。但是,就算找到了表中一個單詞“boyce”的行,數(shù)據(jù)庫也不會停止檢索,因為剩下的每一行都有可能是一個單詞“boyce”的行,也就是說,知道所有行都被檢索后,數(shù)據(jù)庫才會停止檢索并返回查詢結(jié)果。其實就是做了一個全表檢索。其實,如果一個表只有一百行甚至幾千行數(shù)據(jù),就算全表檢索我們也不會又什么明顯的感覺,但是隨著數(shù)據(jù)的膨脹變大,幾萬行數(shù)據(jù)甚至更多時,整表檢索可能就是一件令人恐懼的事情。如果這樣的事情發(fā)生了,除了等待令人恐怖的檢索,我們還可以做什么呢!使用肉眼去看,這樣可能不是一個明智的做法,正常人干不出這事。
就像這個小標題一樣,我們可以使用索引提高性能。索引是通過使用指針的指向減少了檢索數(shù)據(jù)表記錄數(shù)量來提高性能的。
?
索引
索引是一個可以存儲數(shù)據(jù)表列值的數(shù)據(jù)結(jié)構(gòu)(通常都是R-tree)。索引創(chuàng)建在表中列上面。一個很重要的內(nèi)容就是索引包含表中的列值,并且這些值被存儲到了數(shù)據(jù)結(jié)構(gòu)中。簡單易記的一句話,索引就是數(shù)據(jù)結(jié)構(gòu)。
那么可不可以說,索引就是B-tree呢?并不是這樣的,除了有B-tree索引,還有hash索引、R-tree索引、bitmap索引
B-tree 索引
這是最常用的索引。因為,B-tree的索引在查找、刪除、插入操作時的時間復雜度是對數(shù)時間。另外一個重要的原因是,可以把數(shù)據(jù)存儲在B-tree中。但是,索引使用什么樣的數(shù)據(jù)結(jié)構(gòu)是由RDBMS(關(guān)系型數(shù)據(jù)庫管理系統(tǒng))決定的。有時候在創(chuàng)建索引的時候也可以指定索引的數(shù)據(jù)結(jié)構(gòu)類型。
正因為索引是基于數(shù)據(jù)結(jié)構(gòu)存儲列值值的,所以檢索這些值得時候會更快。B-tree 索引的數(shù)據(jù)結(jié)構(gòu)也是一個有序的結(jié)構(gòu)。索引提升性能的主要原因是什么呢?
現(xiàn)在在[WordName] 列上創(chuàng)建B-tree索引,這就意味著,在使用上面的語句
1: SELECT * FROM [Words] 2: WHERE [WordName] = 'boyce'不會再進行全表的掃描。因為索引是可能是按照[WordName] 的字母進行了排序,這就表明,所有以”b” 開頭單詞的索引是挨著的。更重要的是索引中存儲著指向列值實際數(shù)據(jù)行的指針。
?
Hash 索引
這是可能被索引使用的另一個數(shù)據(jù)結(jié)構(gòu)類型。在進行查找操作時,使用hash 索引。的效率很高。因此,當使用一個語句去比較字符串,然后返回結(jié)果集,這樣的操作使用hash 索引是很快的。就像前面的語句
1: SELECT * FROM [Words] 2: WHERE [WordName] = 'boyce'在列[WordName] 上創(chuàng)建hash 索引是一個很好的。這時,列值將插入到hash 表中和一個鍵對應,并和實際的數(shù)據(jù)行有一個映射關(guān)系,也就是該鍵是一個指向表中數(shù)據(jù)行的指針。hash 表實際是基于關(guān)聯(lián)數(shù)組,假如有這樣一個語句“boyce = 0×28936”,0×28936是關(guān)聯(lián)到存儲在內(nèi)存中的boyce。在hash表索引中查找“boyce”的值并返回內(nèi)存中的數(shù)據(jù),要比檢索整個表的[WordName]列值要快得多。
照這樣的說法,是不是以后創(chuàng)建hash 索引好了?
其實不然
hash 表不是一個被排序的數(shù)據(jù)結(jié)構(gòu),很多類型的hash索引查詢根本就沒有性能的提升。比如。檢索300頁以內(nèi)的所有單詞。因為,hash 表擅長的是檢索鍵值對,也就是說,檢索語句檢查相等性(如,“WHERE [WordName] = “boyce” ”)。在hash 表中的鍵值是沒有排序的,在存儲的時候也沒有任何的排序規(guī)則。因為hash 索引不夠靈活。所以,hash 索引不是默認索引的數(shù)據(jù)結(jié)構(gòu)。
是不是,創(chuàng)建所有的索引使用默認的b-tree數(shù)據(jù)結(jié)構(gòu)就完事大吉了呢?
下面的情況還是最好考慮使用hash 索引:
表中存在字段過長,這樣的列是不適合創(chuàng)建索引的,創(chuàng)建索引的原則是索引不能太寬。
對于varchar(max)、nvarchar(max) 和 varbinary(max)的大值數(shù)據(jù)類型也不適合創(chuàng)建索引。
其他類型
使用R-tree 數(shù)據(jù)結(jié)構(gòu)的索引,這個主要是解決一些特定的問題。比如,找到方圓五百米的美女/帥哥,這是使用R-tree 索引,性能會有一定的提升。
還有bitmap 索引,在列值為Boolean值時,該類索引是相當有效的。一般用在選擇性列上。
?
指針
有一個問題:在索引中檢索一個值(比如,boyce),是怎么樣也找到該行其他的列的值呢([WordID]、[WordPage]……)?
可能會說,So easy!因為存在指針。
是這樣的,還是讓我來啰嗦一下。
索引中存儲指向相應行的指針。這個指針是關(guān)聯(lián)到一塊內(nèi)存,該內(nèi)存中存儲了相應數(shù)據(jù)在硬盤的地址。也就是說,添加為索引的列值是存儲在索引中,指向相應數(shù)據(jù)行的指針也是存儲在索引中。這就意味著,[WordName] 在索引中就是像這樣(“boyce”,“0×82937”),那么,0×82937的地址就是“boyce” 所在行在磁盤中的地址。通過這個例子,可以看出, 單值得指針其實沒有用的,是沒有意義的,因為他不能得到相應數(shù)據(jù)行的值。
?
索引百利無一害
索引創(chuàng)建在表的列上,這個概念大家已經(jīng)非常清晰了。索引只是存儲了特定的列,并沒有把表中所有的列全部存儲到索引中。例如,在[WordName] 列上創(chuàng)建索引,這就意味著,[WordID],[WordPage]…… 沒有存儲在索引中。如果創(chuàng)建索引在所有的列上,那就相當于把 整個表復制了一份,這會占據(jù)很大的空間并且效率也很低。
現(xiàn)在我們知道,創(chuàng)建索引其實會占據(jù)一定空間的,越大的表,創(chuàng)建索引占據(jù)的空間越大。還有,在所添加、刪除、和更新行的時候,都需要相應的維護索引,這樣數(shù)據(jù)庫的性能可能會降低。
一般的規(guī)則,被頻繁檢索的列,才在該列創(chuàng)建索引。
轉(zhuǎn)載于:https://www.cnblogs.com/jameslif/p/3664013.html
總結(jié)
以上是生活随笔為你收集整理的[数据库基础]——索引详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [物理学与PDEs]第3章第2节 磁流体
- 下一篇: [转]SQL2005后的ROW_NUMB