《MySQL 學習筆記》 索引
MySQL 索引
索引用於快速找出在某個列中有一特定值的行。不使用索引, MySQL必須從第1條記錄,開始讀完整個表,直到找出相關的行。表越大,查詢數據所花費的時間越多。如果表中查詢的,列有一個索引, MySQL能快速到達某個位置去搜尋數據文件,而不必查看所有數據。
- 索引的簡介
- 索引的含義和特點
- 索引的分類
- 索引的設計原則
- 索引的創建
- 創建表的時候創建索引
- 在已經存在的表上創建索引
- 索引的刪除
索引簡介
索引是對數據庫表中的一列或者多列的值進行排序的一種結構,使用索引可以提高數據庫中特定數據的查詢速度。
索引的含義和特點
索引是一個單獨的、存儲在磁盤上的數據庫結構,它們包含著對數據表裏所有記錄的引用指針。使用索引用於快速找出在某個或多個列中有一特定值的行,所有 MySQL列類型都可以被索引,對相關列使用索引是提高查詢操作速度的最佳途徑。
這裏打個比方:比如我們要查找num=1000,如果沒有索引,那麽MySQL將會遍歷整個表,直到找到1000這一行為止。如果有索引的情況下,當我們查找num時,MySQL不需要任何掃面,直接在索引裏找到數據的位置,這樣一來提高了數據庫的查詢效率。
索引是在存儲引擎中實現的,因此,每種存儲引擎的索引都不一定完全相同,並且每種存諸引擎也不一定支持所有索引類型。根據存儲引擎定義每個表的最大索引數和最大索引長度。
存儲引擎支持每個表至少16個索引,總索引長度至少為256字節。大多數存儲引擎有更高的限制。 MySQL中索引的存儲類型有兩種: BTREE和HASH,具體和表的存儲引擎相關;
MyISAM和 InnoDB存儲引擎只支持 BTREE索引; MEMORY/HEAP存儲引擎可以支持HASH和 BTREE索引。
索引的優點:
1.通過創建唯一索引,可以保證數據庫表中每一行數據的唯一性。
2.可以大大加快數據的查詢速度。
3.在實現數據的參考完整性方面,可以加速表和表之間的連接。
索引的缺點:
1.維護索引要花費大量時間,並且隨著數據量的增加所耗費的時間也會增加。
2.索引占用磁盤空間,每一個索引要占一定得物理空間,如果有大量索引,索引文件可能比數據文件更快達到最大文件尺寸。
3.當對數據進行增刪改查時,索引也需要動態調整,大大降低了數據的可維護性。
索引的分類
普通索引和唯一索引:
普通索引是 MySQL中的基本索引類型,允許在定義索引的列中插入重復值和空值。
唯一索引,索引列的值必須唯一,但允許有空值。如果是組合索引,則列值的組合必須唯一。
主鍵索引是一種特殊的唯一索引,不允許有空值。
單列索引和組合索引:
單列索引即一個索引只包含單個列,一個表可以有多個單列索引。
組合索引指在表的多個字段組合上創建的索引,只有在查詢條件中使用了這些字段的左邊字段時,索引才會被使用。使用組合索引時遵循最左前綴集合。
全文索引:
全文索引類型為 FULLTEXT,在定義索引的列上支持值的全文查找,允許在這些索引列中插入重復值和空值。全文索引可以在CHAR、VARCHAR或者TEXT類型的列上創建。MySQL中只有 MyISAM存儲引擎支持全文索引。
空間索引:
空間索引是對空間數據類型的字段建立的索引, MySQL中的空間數據類型有4種,分別是: GEOMETRY、 POINT、 LINESTRING和 POLYGON。 MySQL使用 SPATIAL關鍵字進行擴展,使得能夠用於創建正規索引類似的語法創建空間索引。創建空間索引的列,必須將其聲明為 NOT NULL,空間索引只能在存儲引擎為 MyISAM的表中創建。
索引的設計原則
(1)索引並非越多越好,一個表中如有大量的索引,不僅占用磁盤空間,而且會影響INSERT、DELETE、UPDATE等語句的性能,因為當表中的數據更改的同時,索引也會進行調整和更新。
(2)避免對經常更新的表進行過多的索引,並且索引中的列盡可能少。而對經常用於查詢的字段應該創建索引,但要避免添加不必要的字段。
(3)數據量小的表最好不要使用索引,由於數據較少,查詢花費的時間可能比遍歷索引的時間還要短,索引可能不會產生優化效果。
(4)在條件表達式中經常用到的不同值較多的列上建立索引,在不同值很少的列上不要建立索引。比如在學生表的“性別”字段上只有“男”與“女”兩個不同值,因此就無須建立索引。如果建立索引不但不會提高查詢效率,反而會嚴重降低數據更新速度。
(5)當唯一性是某種數據本身的特征時,指定唯一索引。使用唯一索引需能確保定義的列的數據完整性,以提高查詢速度。
(6)在頻繁進行排序或分組(即進行 group by或 order by操作)的列上建立索引,如果待排序的列有多個,可以在這些列上建立組合索引。
創建索引
MySQL支持多種方法在單個或多個列上創建索引,在創建表的定義語句create table 中指定索引列,使用alter table 語句在已經存在的表上添加一個索引,或者使用create index語句同樣也可以實現效果。
創建表的時候創建索引
語法格式:
create table table_name [col_name data_type] [unique | fulltext | spatial] [index | key][index_name] (col_name [length]) [ASC | DESC] unique | fulltext | spatial #可選參數,分別表示唯一索引,全文索引,空間索引 index | key #兩者作用相同,用來指定創建索引 col_name #需要創建索引的字段列,此列必須從數據表中定義的列中選擇 length #可選參數,表示索引長度,只用字符串類型才能制定索引長度 ASC | DESC #指定升序或者降序的索引值存儲
創建一個普通索引
最基本的索引類型,沒有唯一性之類的限制,其作用只是加對快數據的訪問速度。
例如:在book表中的year_public字段上建立普通索引,SQL語句如下:
MariaDB [lyshark]> create table book -> ( -> bookid int not null, -> bookname varchar(255) not null, -> authors varchar(255) not null, -> info varchar(255) null, -> comment varchar(255) null, -> year_public year not null, -> index(year_public) -> ); Query OK, 0 rows affected (0.03 sec) MariaDB [lyshark]> desc book; +-------------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------------+--------------+------+-----+---------+-------+ | bookid | int(11) | NO | | NULL | | | bookname | varchar(255) | NO | | NULL | | | authors | varchar(255) | NO | | NULL | | | info | varchar(255) | YES | | NULL | | | comment | varchar(255) | YES | | NULL | | | year_public | year(4) | NO | MUL | NULL | | +-------------+--------------+------+-----+---------+-------+ 6 rows in set (0.00 sec)
執行完語句後,我們可以使用show create table 查看表結構:
MariaDB [lyshark]> show create table book \G; *************************** 1. row *************************** Table: book Create Table: CREATE TABLE `book` ( `bookid` int(11) NOT NULL, `bookname` varchar(255) NOT NULL, `authors` varchar(255) NOT NULL, `info` varchar(255) DEFAULT NULL, `comment` varchar(255) DEFAULT NULL, `year_public` year(4) NOT NULL, #成功建立也索引 KEY `year_public` (`year_public`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 1 row in set (0.00 sec)
使用explain語句查看索引是否正在使用:
MariaDB [lyshark]> explain select * from book where year_public=990 \G; *************************** 1. row *************************** id: 1 select_type: SIMPLE table: book type: ref possible_keys: year_public key: year_public key_len: 1 ref: const rows: 1 Extra: Using index condition 1 row in set (0.00 sec) ERROR: No query specified
在已經存在的表上創建索引
刪除索引
《MySQL 學習筆記》 索引