1. 程式人生 > >《MySQL 學習筆記》 索引

《MySQL 學習筆記》 索引

至少 shark HERE 性方面 我們 特定 date 執行 需要

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.在實現數據的參考完整性方面,可以加速表和表之間的連接。

4.使用分組和排序子句進行數據查詢時,也可以顯著減少查詢中分組和排序的時間。

索引的缺點:

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 學習筆記》 索引