本文從索引的概念入手,簡單介紹了索引的特點和分類,並通過實例對創建和刪除索引進行說明。索引是個好東西,但卻並非多多益善,這一點在索引設計原則中有說到。 ...
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 總結
本文從索引的概念入手,簡單介紹了索引的特點和分類,並通過實例對創建和刪除索引進行說明。索引是個好東西,但卻並非多多益善,這一點在索引設計原則中有說到。