1 引言
在沒有索引的情況下,如果要尋找特定行,資料庫可能要遍歷整個資料庫,使用索引後,資料庫可以根據索引找出這一行,極大提高查詢效率。本文是對MySQL資料庫中索引使用的總結。
2 索引簡介
索引是一個單獨的、儲存自磁碟上的資料庫結構,包含著對資料表裡所有記錄的引用指標。使用索引用於快速找出在某個或多個列中有一特定值的行,所有MySQL列型別都可以被索引,對相關列使用索引是提高查詢操作速度的最佳途徑。
小時候我們都用過現代漢語詞典,當我們要查詢某個字時,如果沒有目錄,我們需要一頁一頁去尋找,有了目錄,直接根據目錄就可以找到那個字。資料庫中的索引就相當於現代漢語詞典中的目
錄,目錄中存放在一個指向內容真實地址的指標,可以提高我們查詢的速度。
另外需要說明的是,索引是在儲存引擎中實現的,因此,每種儲存引擎的索引都不一定完全相同,並且每種儲存引擎也不一定支援所有的索引型別。MySQL中索引的儲存型別有兩種:BTREE和HASH,具體和表的儲存引擎相關。MyISAM和InnoDB儲存引擎只支援BTREE索引,MEMORY/HEAP儲存引擎可以支援HASH和BTREE索引。
索引的有點主要有一下幾條:
(1)通過建立唯一索引,可以保證資料庫中每一行資料的唯一性。
(2)可以大大加快資料的查詢速度,這也是建立索引的最主要的原因。
(3)在實現資料的參考完整性方面,可以加速表和表之間的連線。
(4)在使用分組和排序子句進行資料查詢時,也可以顯著減少查詢中分組和排序的時間。
當然,索引也有許多不利方面,主要表現在以下幾個方面:
(1)建立索引和維護索引都要消耗時間,並且隨著資料量的增加所耗費的時間也會增加。
(2)索引需要佔用磁碟空間。
(3)對資料表進行增加、刪除、修改時,索引也要動態維護,這樣就降低了資料的維護速度。
3 索引的分類
MySQL的索引可以分為以下幾類:
(1)普通索引和唯一索引
普通索引和唯一索引是根據索引的功能來劃分。
普通索引是MySQL中的基本索引型別,允許在定義索引的列中插入重複值和空值。
唯一索引的索引列的值必須唯一,但允許空值。如果是組合索引,則列的值組合必須唯一。主鍵索引是一種特殊的唯一索引,不允許有空值。
(2)單列索引和組合索引
事實上,單列索引和組合索引的劃分是根據建立索引時所引用的列的數量來劃分。
單列索引是隻一個索引只包含單個列,一個表可以有多個單列索引。
組合索引指在表的多個欄位組合上建立索引,但只有在查詢條件中使用了這些欄位的左邊欄位時,索引才會被使用。
組合索引可以起到多個索引的作用,但是使用時並不是隨便哪個欄位都可以使用索引的,而是遵從“最左字首”:利用索引中最左邊的列集列匹配行,這樣的列集稱為最左字首。例如由id、name、age這3個欄位欄位構成的索引,索引行中按id/name/age的順序存放,索引可以搜尋下面欄位組合:(id, name , age)、(id , name)、(id)。如果不構成索引的最左邊的字首,MySQL不能使用區域性索引,如(age)、(name, age)都不能使用索引進行查詢。
(3)全文索引
全文索引型別為FULLTEXT,在定義索引的列上至此值需得全文查詢,允許在這些索引列上插入空值和重複值。
(4)空間索引
很少用到,本文不涉及。
4 建立索引
建立索引的方式有三種:
(1)直接建立索引
語法結果如下:
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name ON table_name (column(length),…) [ASC|DESC]
a. 建立普通索引
create index bknameIndex on book(bookname) ;
b. 建立唯一索引
create unique index unique_Index on book(bookId) ;
c. 建立單列索引
create index single_Index on book(comment(10)) ;
d. 建立多列索引
create index mutil_Index on book(authors(20) , info(20)) ;
e. 建立全文索引
create fulltext index fulltext_Index on book(info) ;
(2)通過修改表結構的方式新增索引
語法結構如下:
ALTER TABLE table_name ADD [UNIQUE|FULLTEXT|SPATIAL] [INDEX|KEY] index_name (column(length),…) [ASC|DESC]
a. 建立普通索引
alter table book add index bkName(bookname(30)) ;
b. 建立唯一索引
alter table book add unique index uniqueIndex(bookId) ;
c. 建立單列索引
alter table book add index signalIndex2 on(comment(50)) ;
d. 建立多列索引
alter table book add index mutilIndex (authors(30) , info(50)) ;
e. 建立全文索引
alter table book add fulltext index fulltextIndex (info) ;
(3)建立表的時候同時建立索引
語法結構如下:
CREATE TABLE table_name ( ……(建立欄位和約束), [UNIQUE|FULLTEXT|SPATIAL] [INDEX|KEY] [INDEX|KEY] [index_name] (col_name [length]) [ASC|DESC] )
a. 建立普通索引
create table book( bookid int not null , bookname VARCHAR(255) not null , authors VARCHAR(255) not null , info VARCHAR(255) not null , comment VARCHAR(255) not null , year_publication YEAR not null , index pub_index(year_publication) );
b. 建立唯一索引
create table book( …… unique index pub_index(bookid) );
c. 建立單列索引
create table book( …… index single_index(authors) );
d. 多列索引
create table book( …… index mutil_index(bookid, authors) );
e. 建立全文索引
create table book( …… fulltext index fulltext_index(info) );
(注:MySQL5.7中預設儲存引擎為InnoDB,在這裡建立表時需要修改表的儲存引擎為MyISAM,否則會出錯)
5 刪除索引
(1)使用ALTER TABLE刪除索引
語法結構:
ALTER TABLE table_name DROP INDEX index_name ;
(注:有AUTO_INCREMENT約束的欄位的唯一索引不能被刪除)
示例:刪除book表中名為fulltext_Index的索引
alter table book drop index fulltext_Index ;
(2)使用DROP INDEX語句刪除索引
語法結構:
DROP INDEX index_name ON table_name ;
示例:刪除book表中名為fulltext_Index的索引
drop index mutil_index on book ;
6 索引設計原則
索引設計不合理或者缺少索引都會對資料庫效能造成不良影響。那麼設計索引是該如何考慮呢?
(1)索引並非越多越好,一個表中如果有大量的索引,不僅佔用磁碟空間,而且會影響INSERT、DELETE、UPDATE等語句的效能,因為當表中的資料更改的同時,索引也會進行調整和更新。
(2)資料量小的表最好不要使用索引,由於資料量較小,查詢所花費的時間可能比表裡索引的時間還要短,索引可能不會產生優化的效果。
(3)避免對經常更新的表進行過多的索引,並且索引中的列儘可能少。對經常用於查詢的欄位應該建立索引,但要避免新增不必要的欄位。
(4)在條件表示式中經常用到的不同值較多的列上建立索引,在不同值很少的列(例如性別欄位,只有男女兩個取值)不要建立索引。
(5)當唯一性是資料本身的特徵時,指定唯一索引,可確保資料完整性並提高查詢速度。
(6)在頻繁進行排序、分組的列上建立索引,如果排序的列有多個,可以在這些列上建立組合索引。
7 總結
本文從索引的概念入手,簡單介紹了索引的特點和分類,並通過例項對建立和刪除索引進行說明。索引是個好東西,但卻並非多多益善,這一點在索引設計原則中有說到。