今天介紹關於UNIQUE INDEX.
以第18天建立的AVGals這個Table為例.
這個Table經過幾天的示範,也有增加了索引.
我們可以用這道指令來看他的定義.
SHOW CREATE TABLE AVGals\G
*************************** 1. row ***************************
Table: AVGals
Create Table: CREATE TABLE `AVGals` (
`galid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
`birth_year` year(4) DEFAULT NULL,
PRIMARY KEY (`galid`),
KEY `name` (`name`),
KEY `birth_year` (`birth_year`),
KEY `birth_year_2` (`birth_year`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
可以看到除了PRIMAEY KEY以外,尚有以name欄位為key的一般索引,另有以birth_year欄位為key的一般索引兩個.
接著回顧一下第7天介紹的HANDLER.
我們來看看一般索引的情況下,MySQL的SESSION STATUS中關於HANDLER的情況變化.
首先將狀態清除.
FLUSH STATUS;
SHOW SESSION STATUS LIKE 'Handler_read_next';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Handler_read_next | 0 |
+-------------------+-------+
查詢初音.
SELECT *
FROM AVGals
WHERE name = '初音みのり';
SHOW SESSION STATUS LIKE 'Handler_read_next';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Handler_read_next | 1 |
+-------------------+-------+
Handler_read_next 的值為1,代表的意義,
就是雖然我們已經建立了以name欄位為key的一般索引,
但是MySQL還需要作index scan,因為不能確保還有沒有
同樣的資料.
接著我們將name這個一般索引刪掉,再建立一個以name欄位
為key的UNIQUE INDEX.
ALTER TABLE AVGals DROP INDEX name;
ALTER TABLE AVGals ADD UNIQUE INDEX(name);
重複上面的步驟.
FLUSH STATUS;
SHOW SESSION STATUS LIKE 'Handler_read_next';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Handler_read_next | 0 |
+-------------------+-------+
SELECT *
FROM AVGals
WHERE name = '初音みのり';
SHOW SESSION STATUS LIKE 'Handler_read_next';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Handler_read_next | 0 |
+-------------------+-------+
因為是UNIQUE INDEX,所以MySQL確定這是唯一的,就無須往下再掃描索引了.
有助於提高運作的效率.