一、簡介
索引是一種特殊的數據庫結構,可以用來快速查詢數據庫表中的特定記錄。索引是提高數據庫性能的重要方式。在MySQL中,所有的數據類型都可以被索引。MySQL的索引包括:普通索引、唯一性索引、全文索引、單列索引、多列索引、空間索引。本文主要講解以下幾個方面:
1、索引的含義和特點
2、索引的分類
3、如何設計索引
4、如何創建索引
5、如何刪除索引
1、 索引的含義和特點
索引由數據庫表中一列或多列組合而成,其作用是提高對錶中數據的查詢速度。
索引是創建在表上的,是對數據庫表中的一列或者多列的值進行排序的一種結構。索引可以提高查詢的速度。
通過索引,查詢數據時可以完全不必讀完記錄的所有信息,而只是查詢索引列。否則,數據庫系統將讀取每條記錄的所有信息進行匹配。例如,索引相當於新華字典的音序表。如果要查"郭"字,如果不使用音序,需要從字典的400頁中逐頁來找。但是,如果提取拼音出來,構成音序表,就只需要從10多頁的音序表中直接查找。這樣就可以大大節省時間。因此,使用索引可以很大程度上提高數據庫的查詢速度。這樣有效的提高了數據庫系統的性能。
不同的存儲引擎定義了每個表的最大索引數和最大索引長度。所有存儲引擎對每個表至少支持16個索引,總索引長度至少爲256字節。有些存儲引擎支持更多的索引數和更大的索引長度。索引有兩種存儲類型,包括B型樹(BTREE)索引和哈希(HASH)索引。InnoDB和MyISAM存儲引擎支持BTREE索引,MEMORY存儲引擎支持HASH索引和BTREE索引,默認爲前者。
1.1、索引的優缺點
索引有其明顯的優勢,也有其不可避免的缺點。
索引的優點是:
可以提高檢索數據的速度,這是創建索引的最主要的原因;
對於有依賴關係的子表和父表之間的聯合查詢時,可以提高查詢速度;
使用分組和排序子句進行數據查詢時,同樣可以顯著節省查詢中分組和排序的時間。
索引的缺點是:
創建和維護索引需要耗費時間,耗費時間的數量隨着數據量的增加而增加;
索引需要佔用物理空間,每一個索引要佔一定的物理空間;
增加、刪除和修改數據時,要動態的維護索引,造成數據的維護速度降低了 。
因此,選擇使用索引時,需要綜合考慮索引的優點和缺點。
技巧:索引可以提高查詢的速度,但是會影響插入記錄的速度。因爲,向有索引的表中插入記錄時,數據庫系統會按照索引進行排序。這樣就降低了插入記錄的速度,插入大量記錄時的速度影響更加明顯。這種情況下,最好的辦法是先刪除表中的索引,然後插入數據。插入完成後,再創建索引。
2、索引的分類
2.1 普通索引
2.2 唯一性索引
2.3 全文索引
2.4 單列索引
2.5 多列索引
2.6 空間索引
3、索引的設計原則
爲了使索引的使用效率更高,在創建索引時,必須考慮在哪些字段上創建索引和創建什麼類型的索引。
3.1 選擇唯一性索引
唯一性索引的值是唯一的,可以更快速的通過該索引來確定某條記錄。例如,學生表中學號是具有唯一性的字段。爲該字段建立唯一性索引可以很快的確定某個學生的信息。如果使用姓名的話,可能存在同名現象,從而降低查詢速度。
3.2 爲經常需要排序、分組和聯合操作的字段建立索引
經常需要ORDER BY、GROUP BY、DISTINCT和UNION等操作的字段,排序操作會浪費很多時間。如果爲其建立索引,可以有效地避免排序操作。
3.3 爲常作爲查詢條件的字段建立索引
如果某個字段經常用來做查詢條件,那麼該字段的查詢速度會影響整個表的查詢速度。因此,爲這樣的字段建立索引,可以提高整個表的查詢速度。
3.4 限制索引的數目
索引的數目不是越多越好。每個索引都需要佔用磁盤空間,索引越多,需要的磁盤空間就越大。修改表時,對索引的重構和更新很麻煩。越多的索引,會使更新表變得很浪費時間。
3.5 儘量使用數據量少的索引
如果索引的值很長,那麼查詢的速度會受到影響。例如,對一個CHAR(100)類型的字段進行全文檢索需要的時間肯定要比對CHAR(10)類型的字段需要的時間要多。
3.6 儘量使用前綴來索引
如果索引字段的值很長,最好使用值的前綴來索引。例如,TEXT和BLOG類型的字段,進行全文檢索會很浪費時間。如果只檢索字段的前面的若干個字符,這樣可以提高檢索速度。
3.7 刪除不再使用或者很少使用的索引
表中的數據被大量更新,或者數據的使用方式被改變後,原有的一些索引可能不再需要。數據庫管理員應當定期找出這些索引,將它們刪除,從而減少索引對更新操作的影響。
注意:選擇索引的最終目的是爲了使查詢的速度變快。上面給出的原則是最基本的準則,但不能拘泥於上面的準則。讀者要在以後的學習和工作中進行不斷的實踐。根據應用的實際情況進行分析和判斷,選擇最合適的索引方式。
4、創建索引
創建索引是指在某個表的一列或多列上建立一個索引,以便提高對錶的訪問速度。創建索引有3種方式,這3種方式分別是:創建表的時候創建索引、在已經存在的表上創建索引、使用ALTER TABLE語句來創建索引。
4.1 創建表的時候創建索引
創建表時可以直接創建索引,這種方式最簡單、方便。其基本形式如下:
- CREATE TABLE 表名 ( 屬性名 數據類型 [完整性約束條件],
- 屬性名 數據類型 [完整性約束條件],
- ......
- 屬性名 數據類型
- [ UNIQUE | FULLTEXT | SPATIAL ] INDEX | KEY
- [ 別名 ] ( 屬性名1 [(長度)] [ ASC | DESC] )
- );
其中,UNIQUE是可選參數,表示索引爲唯一性索引;FULLTEXT是可選參數,表示索引爲全文索引;SPATIAL也是可選參數,表示索引爲空間索引;INDEX和KEY參數用來指定字段爲索引的,兩者選擇其中之一就可以了,作用是一樣的;"別名"是可選參數,用來給創建的索引取的新名稱;"屬性1"參數指定索引對應的字段的名稱,該字段必須爲前面定義好的字段;"長度"是可選參數,其指索引的長度,必須是字符串類型纔可以使用;"ASC"和"DESC"都是可選參數,"ASC"參數表示升序排列,"DESC"參數表示降序排列。
1、創建普通索引
【示例1】創建一個表名爲user的表,在表中的id字段上建立索引。
CREATE TABLE USER ( id INT, NAME VARCHAR (50), company VARCHAR (50), INDEX (id));
2、創建唯一性索引
【示例2】下面創建一個表名爲user2的表,在表中的id字段上建立名爲user2_id的唯一性索引,且以升序的形式排列。
CREATE TABLE user2 ( id INT UNIQUE, NAME VARCHAR (20), UNIQUE INDEX user2_id (id ASC)
);
結果可以看到,id字段上已經建立了一個名爲index2_id的唯一性索引。這裏的id字段可以沒有進行唯一性約束,也可以在該字段上成功創建唯一性索引。但是,這樣可能達不到提高查詢速度的目的。
3、創建全文索引
【示例3】下面創建一個表名爲user3的表,在表中的info字段上建立名爲user3_ info的全文索引。
CREATE TABLE user3 ( id INT, INFO VARCHAR (30), FULLTEXT INDEX user3_info (info)
) ENGINE = MyISAM;
結果可以看到,info字段上已經建立了一個名爲index3_info的全文索引。如果表的存儲引擎不是MyISAM存儲引擎,系統會提示"ERROR 1214 (HY000): The used table type doesn't support FULLTEXT indexes"。
注意:目前只有MyISAM存儲引擎支持全文索引,InnoDB存儲引擎還不支持全文索引。因此,在創建全文索引時一定注意表的存儲引擎的類型。對於經常需要索引的字符串、文字數據等信息,可以考慮存儲到MyISAM存儲引擎的表中。
4、創建單列索引
【示例4】 下面創建一個表名爲user4的表,在表中的subject字段上建立名爲user4_st的單列索引。
CREATE TABLE user4 ( id INT, SUBJECT VARCHAR (30), INDEX user4_st (SUBJECT(10))
);
結果可以看到,subject字段上已經建立了一個名爲index4_st的單列索引。細心的讀者可能會發現,subject字段長度爲20,而index4_st索引的長度只有10。這樣做的目的還是爲了提高查詢速度。對於字符型的數據,可以不用查詢全部信息,而只查詢其前面的若干字符信息。
5、創建多列索引
【示例5】下面創建一個表名爲index5的表,在表中的name和sex字段上建立名爲index5_ns的多列索引
CREATE TABLE index5 (id INT , name VARCHAR(20) , sex CHAR(4) , INDEX index5_ns ( name, sex ) );
技巧:使用多列索引時一定要特別注意,只有使用了索引中的第一個字段時纔會觸發索引。如果沒有使用索引中的第一個字段,那麼這個多列索引就不會起作用。因此,在優化查詢速度時,可以考慮優化多列索引。
6、創建空間索引
創建空間索引時必須使用SPATIAL參數來設置。創建空間索引時,表的存儲引擎必須是MyISAM類型。而且,索引字段必須有非空約束。
【示例6】 下面創建一個表名爲index6的表,在表中的space字段上建立名爲index6_sp的空間索引。
CREATE TABLE index6 (id INT , space GEOMETRY NOT NULL, SPATIAL INDEX index6_sp (space ) )ENGINE=MyISAM; 結果可以看到,space字段上已經建立了一個名爲index6_sp的空間索引。值得注意的是,space字段是非空的,而且數據類型是GEOMETRY類型。這個類型是空間數據類型。空間類型包括GEOMETRY、POINT、LINESTRING和POLYGON類型等。這些空間數據類型平時很少用到。
4.2 在已經存在的表上創建索引
1.創建普通索引
【示例7】 下面在example0表中的id字段上建立名爲index7_id的索引。CREATE INDEX index7_id ON example0 ( id ) ;
2.創建唯一性索引
【示例8】 下面在index8表中的course_id字段上建立名爲index8_id的唯一性索引。
CREATE UNIQUE INDEX index8_id ON index8( course_id ) ;
3.創建全文索引
【示例9】 下面在index9表中的info字段上建立名爲index9_info的全文索引。
CREATE FULLTEXT INDEX index9_info ON index9( info ) ;
4.創建單列索引
【示例10】 下面在index10表中的address字段上建立名爲index10_addr的單列索引。address字段的數據類型爲VARCHAR(20),索引的數據類型爲CHAR(4)。
CREATE INDEX index10_addr ON index10( address(4) ) ;
5.創建多列索引
【示例11】 下面在index11表中的name和address字段上建立名爲index11_na的多列索引。
CREATE INDEX index11_na ON index11( name, address ) ;
6.創建空間索引
【示例12】 下面在index12表中的line字段上建立名爲index12_line的多列索引。4.3、用ALTER TABLE語句來創建索引
1.創建普通索引
【示例13】 下面在example0表中的name字段上建立名爲index13_name的索引。
ALTER TABLE example0 ADD INDEX index13_name ( name(20) ) ;
2.創建唯一性索引
【示例14】 下面在index14表中的course_id字段上,建立名爲index14_id的唯一性索引。ALTER TABLE index14 ADD UNIQUE INDEX index14_id ( course_id ) ;
3.創建全文索引
【示例15】 下面在index15表中的info字段上建立名爲index15_info的全文索引。
ALTER TABLE index15 ADD FULLTEXT INDEX index15_info ( info ) ;
4.創建單列索引
【示例16】 下面在index16表中的address字段上建立名爲index16_addr的單列索引。address字段的數據類型爲VARCHAR(20),索引的數據類型爲CHAR(4)。ALTER TABLE index16 ADD INDEX index16_addr( address(4) ) ;
5.創建多列索引
【示例17】 下面在index17表中的name和address字段上建立名爲index17_na的多列索引。
ALTER TABLE index17 ADD INDEX index17_na( name, address ) ;
6.創建空間索引
【示例18】 下面在index18表中的line字段上建立名爲index18_line的多列索引。
ALTER TABLE index18 ADD SPATIAL INDEX index18_line( line ) ;
5、刪除索引
刪除索引是指將表中已經存在的索引刪除掉。一些不再使用的索引會降低表的更新速度,影響數據庫的性能。對於這樣的索引,應該將其刪除。
DROP INDEX 索引名 ON 表名 ;
其中,"索引名"參數指要刪除的索引的名稱;"表名"參數指索引所在的表的名稱。