我的MYSQL學習心得(一)
我的MYSQL學習心得(二)
我的MYSQL學習心得(三)
我的MYSQL學習心得(四)
我的MYSQL學習心得(五)
我的MYSQL學習心得(六)
我的MYSQL學習心得(七)
我的MYSQL學習心得(八)
這一篇《我的MYSQL學習心得(九)》將會講解MYSQL的索引
索引是在存儲引擎中實現的,因此每種存儲引擎的索引都不一定完全相同,並且每種存儲引擎也不一定支持所有索引類型。
根據存儲引擎定義每個表的最大索引數和最大索引長度。所有存儲引擎支持每個表至少16個索引,總索引長度至少為256字節。
大多數存儲引擎有更高的限制。MYSQL中索引的存儲類型有兩種:BTREE和HASH,具體和表的存儲引擎相關;
MYISAM和InnoDB存儲引擎只支持BTREE索引;MEMORY和HEAP存儲引擎可以支持HASH和BTREE索引
索引的優點:
1、通過創建唯一索引,保證數據庫表每行數據的唯一性
2、大大加快數據查詢速度
3、在使用分組和排序進行數據查詢時,可以顯著減少查詢中分組和排序的時間
索引的缺點:
1、維護索引需要耗費數據庫資源
2、索引需要占用磁盤空間,索引文件可能比數據文件更快達到最大文件尺寸
3、當對表的數據進行增刪改的時候,因為要維護索引,速度會受到影響
索引的分類
1、普通索引和唯一索引
主鍵索引是一種特殊的唯一索引,不允許有空值
2、單列索引和復合索引
單列索引只包含單個列
復合索引指多個字段上創建的索引,只有在查詢條件中使用了創建索引時的第一個字段,索引才會被使用。使用復合索引時遵循最左前綴集合
3、全文索引
全文索引類型為FULLTEXT,在定義索引的列上支持值的全文查找,允許在這些索引列中插入重復值和空值。全文索引可以在
CHAR、VARCHAR、TEXT類型列上創建。MYSQL只有MYISAM存儲引擎支持全文索引
4、空間索引
空間索引是對空間數據類型的字段建立的索引,MYSQL中的空間數據類型有4種,
分別是GEOMETRY、POINT、LINESTRING、POLYGON。
MYSQL使用SPATIAL關鍵字進行擴展,使得能夠用於創建正規索引類型的語法創建空間索引。創建空間索引的列,必須
將其聲明為NOT NULL,空間索引只能在存儲引擎為MYISAM的表中創建
以上的索引在SQLSERVER裡都支持
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為需要創建索引的字段列,該列必須從數據表中該定義的多個列中選擇;
index_name指定索引的名稱,為可選參數,如果不指定,MYSQL默認col_name為索引值;
length為可選參數,表示索引的長度,只有字符串類型的字段才能指定索引長度;
asc或desc指定升序或降序的索引值存儲
普通索引
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_publication YEAR NOT NULL, INDEX (year_publication) ) ;
使用SHOW 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_publication` YEAR(4) NOT NULL, KEY `year_publication` (`year_publication`) ) ENGINE=MYISAM DEFAULT CHARSET=latin1
可以發現,book表的year_publication字段成功建立了索引其索引名字為year_publication
我們向表插入一條數據,然後使用EXPLAIN語句查看索引是否有在使用
INSERT INTO BOOK VALUES(12,'NIHAO','NIHAO','文學','henhao',1990) EXPLAIN SELECT * FROM book WHERE year_publication=1990
因為語句比較簡單,系統判斷有可能會用到索引或者全文掃描
EXPLAIN語句輸出結果的各個行的解釋如下:
select_type: 表示查詢中每個select子句的類型(簡單 OR復雜)
type:表示MySQL在表中找到所需行的方式,又稱“訪問類型”,常見類型如下:(從上至下,效果依次變好)
possible_keys :指出MySQL能使用哪個索引在表中找到行,查詢涉及到的字段上若存在索引,則該索引將被列出,但不一定被查詢使用
key: 顯示MySQL在查詢中實際使用的索引,若沒有使用索引,顯示為NULL
key_len :表示索引中使用的字節數,可通過該列計算查詢中使用的索引的長度
ref :表示上述表的連接匹配條件,即哪些列或常量被用於查找索引列上的值
rows :表示MySQL根據表統計信息及索引選用情況,估算的找到所需的記錄所需要讀取的行數
Extra :包含不適合在其他列中顯示但十分重要的額外信息 如using where,using index
參考:MySQL學習系列2--MySQL執行計劃分析EXPLAIN
唯一索引
唯一索引列的值必須唯一,但允許有空值。如果是復合索引則列值的組合必須唯一
建表
CREATE TABLE t1 ( id INT NOT NULL, NAME CHAR(30) NOT NULL, UNIQUE INDEX UniqIdx(id)
SHOW CREATE TABLE t1 查看表結構
SHOW CREATE TABLE t1
CREATE TABLE `t1` ( `id` int(11) NOT NULL, `name` char(30) NOT NULL, UNIQUE KEY `UniqIdx` (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8
可以看到id字段上已經成功建立了一個名為UniqIdx的唯一索引
創建復合索引
CREATE TABLE t3 ( id INT NOT NULL, NAME CHAR(30) NOT NULL, age INT NOT NULL, info VARCHAR (255), INDEX MultiIdx (id, NAME, age (100)) )
SHOW CREATE TABLE t3 CREATE TABLE `t3` ( `id` int(11) NOT NULL, `NAME` char(30) NOT NULL, `age` int(11) NOT NULL, `info` varchar(255) DEFAULT NULL, KEY `MultiIdx` (`id`,`NAME`,`age`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8
由結果可以看到id,name,age字段上已經成功建立了一個名為MultiIdx的復合索引
我們向表插入兩條數據
INSERT INTO t3(id ,NAME,age,info) VALUES(1,'小明',12,'nihao'),(2,'小芳',16,'nihao')
使用EXPLAIN語句查看索引使用情況
EXPLAIN SELECT * FROM t3 WHERE id=1 AND NAME='小芳'
可以看到 possible_keys和 key 為MultiIdx證明使用了復合索引
id select_type table type possible_keys key key_len ref rows Extra ------ ----------- ------ ------ ------------- -------- ------- ----------- ------ ----------- 1 SIMPLE t3 ref MultiIdx MultiIdx 94 const,const 1 Using where
如果我們只指定name而不指定id
EXPLAIN SELECT * FROM t3 WHERE NAME='小芳'
id select_type table type possible_keys key key_len ref rows Extra ------ ----------- ------ ------ ------------- ------ ------- ------ ------ ----------- 1 SIMPLE t3 ALL (NULL) (NULL) (NULL) (NULL) 2 Using where
結果跟SQLSERVER一樣,也是不走索引, possible_keys和key都為NULL
全文索引
FULLTEXT索引可以用於全文搜索。只有MYISAM存儲引擎支持FULLTEXT索引,並且只支持CHAR、VARCHAR和TEXT類型
全文索引不支持過濾索引。
CREATE TABLE t4 ( id INT NOT NULL, NAME CHAR(30) NOT NULL, age INT NOT NULL, info VARCHAR (255), FULLTEXT INDEX FulltxtIdx (info) ) ENGINE = MYISAM
由於MYSQL5.6默認存儲引擎為InnoDB,這裡創建表的時候要修改表的存儲引擎為MYISAM,不然創建索引會出錯
SHOW CREATE TABLE t4
Table Create Table ------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- t4 CREATE TABLE `t4` ( `id` int(11) NOT NULL, `name` char(30) NOT NULL, `age` int(11) NOT NULL, `info` varchar(255) DEFAULT NULL, FULLTEXT KEY `FulltxtIdx` (`info`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8
由結果可以看到,info字段上已經成功建立名為FulltxtIdx的FULLTEXT索引。
全文索引非常適合大型數據集合
在SQLSERVER裡使用全文索引比MYSQL還要復雜
詳細可以參考下面兩篇文章:
關於SQLSERVER的全文目錄跟全文索引的區別
[SQLSERVER]SQL中的全文檢索(轉鄒建)
空間索引
空間索引必須在 MYISAM類型的表中創建,而且空間類型的字段必須為非空
建表t5
CREATE TABLE t5 (g GEOMETRY NOT NULL ,SPATIAL INDEX spatIdx(g))ENGINE=MYISAM
SHOW CREATE TABLE t5 TABLE CREATE TABLE ------ --------------------------------------------------------------------------------------------------------------- t5 CREATE TABLE `t5` ( `g` GEOMETRY NOT NULL, SPATIAL KEY `spatIdx` (`g`) ) ENGINE=MYISAM DEFAULT CHARSET=utf8
可以看到,t5表的g字段上創建了名稱為spatIdx的空間索引。注意創建時指定空間類型字段值的非空約束
並且表的存儲引擎為MYISAM
已經存在的表上創建索引
在已經存在的表中創建索引,可以使用ALTER TABLE或者CREATE INDEX語句
1、使用ALTER TABLE語句創建索引,語法如下
ALTER TABLE table_name ADD [UNIQUE|FULLTEXT|SPATIAL][INDEX|KEY]
[index_name](col_name[length],...)[ASC|DESC]
與創建表時創建索引的語法不同,在這裡使用了ALTER TABLE和ADD關鍵字,ADD表示向表中添加索引
在t1表中的name字段上建立NameIdx普通索引
ALTER TABLE t1 ADD INDEX NameIdx(NAME)
添加索引之後,使用SHOW INDEX語句查看指定表中創建的索引
SHOW INDEX FROM t1 TABLE Non_unique Key_name Seq_in_index Column_name COLLATION Cardinality Sub_part Packed NULL Index_type COMMENT Index_comment ------ ---------- -------- ------------ ----------- --------- ----------- -------- ------ ------ ---------- ------- ------------- t1 0 UniqIdx 1 id A 0 (NULL) (NULL) BTREE t1 1 NameIdx 1 NAME A (NULL) (NULL) (NULL) BTREE
各個參數的含義
1、TABLE:要創建索引的表
2、Non_unique:索引非唯一,1代表是非唯一索引,0代表唯一索引
3、Key_name:索引的名稱
4、Seq_in_index:該字段在索引中的位置,單列索引該值為1,復合索引為每個字段在索引定義中的順序
5、Column_name:定義索引的列字段
6、Sub_part:索引的長度
7、NULL:該字段是否能為空值
8、Index_type:索引類型
可以看到,t1表已經存在了一個唯一索引
在t3表的age和info字段上創建復合索引
ALTER TABLE t3 ADD INDEX t3AgeAndInfo(age,info)
使用SHOW INDEX查看表中的索引
SHOW INDEX FROM t3
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment ------ ---------- ------------ ------------ ----------- --------- ----------- -------- ------ ------ ---------- ------- ------------- t3 1 MultiIdx 1 id A (NULL) (NULL) (NULL) BTREE t3 1 MultiIdx 2 NAME A (NULL) (NULL) (NULL) BTREE t3 1 MultiIdx 3 age A (NULL) (NULL) (NULL) BTREE t3 1 t3AgeAndInfo 1 age A (NULL) (NULL) (NULL) BTREE t3 1 t3AgeAndInfo 2 info A (NULL) (NULL) (NULL) YES BTREE
可以看到表中的字段的順序,第一個位置是age,第二個位置是info,info字段是可空字段
創建表t6,在t6表上創建全文索引
CREATE TABLE t6 ( id INT NOT NULL, info CHAR(255) )ENGINE= MYISAM;
注意修改ENGINE參數為MYISAM,MYSQL默認引擎InnoDB不支持全文索引
使用ALTER TABLE語句在info字段上創建全文索引
ALTER TABLE t6 ADD FULLTEXT INDEX infoFTIdx(info)
使用SHOW INDEX查看索引情況
SHOW INDEX FROM t6
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment ------ ---------- --------- ------------ ----------- --------- ----------- -------- ------ ------ ---------- ------- ------------- t6 1 infoFTIdx 1 info (NULL) (NULL) (NULL) (NULL) YES FULLTEXT
創建表t7,並在空間數據類型字段g上創建名稱為spatIdx的空間索引
CREATE TABLE t7(g GEOMETRY NOT NULL)ENGINE=MYISAM;
使用ALTER TABLE在表t7的g字段建立空間索引
ALTER TABLE t7 ADD SPATIAL INDEX spatIdx(g)
使用SHOW INDEX查看索引情況
SHOW INDEX FROM t7
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment ------ ---------- -------- ------------ ----------- --------- ----------- -------- ------ ------ ---------- ------- ------------- t7 1 spatIdx 1 g A (NULL) 32 (NULL) SPATIAL
2、使用CREATE INDEX語句創建索引,語法如下
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name
ON table_name(col_name[length],...) [ASC|DESC]
可以看到CREATE INDEX語句和ALTER INDEX語句的基本語法一樣,只是關鍵字不同。
我們建立一個book表
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_publication YEAR NOT NULL )
建立普通索引
CREATE INDEX BkNameIdx ON book(bookname)
建立唯一索引
CREATE UNIQUE INDEX UniqidIdx ON book(bookId)
建立復合索引
CREATE INDEX BkAuAndInfoIdx ON book(AUTHORS(20),info(50))
建立全文索引,我們drop掉t6表,重新建立t6表
DROP TABLE IF EXISTS t6 CREATE TABLE t6 ( id INT NOT NULL, info CHAR(255) )ENGINE= MYISAM; CREATE FULLTEXT INDEX infoFTIdx ON t6(info);
建立空間索引,我們drop掉t7表,重新建立t7表
DROP TABLE IF EXISTS t7 CREATE TABLE t7(g GEOMETRY NOT NULL)ENGINE=MYISAM; CREATE SPATIAL INDEX spatIdx ON t7(g)
刪除索引
MYSQL中使用ALTER TABLE或者DROP INDEX語句來刪除索引,兩者實現相同功能
1、使用ALTER TABLE刪除索引
語法
ALTER TABLE table_name DROP INDEX index_name
ALTER TABLE book DROP INDEX UniqidIdx
SHOW CREATE TABLE book
Table Create Table ------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ book 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_publication` year(4) NOT NULL, KEY `BkNameIdx` (`bookname`), KEY `BkAuAndInfoIdx` (`authors`(20),`info`(50)) ) ENGINE=MyISAM DEFAULT CHARSET=utf8
可以看到,book表中已經沒有名為UniqidIdx的唯一索引,刪除索引成功
注意:AUTO_INCREMENT約束字段的唯一索引不能被刪除!!
2、使用DROP INDEX 語句刪除索引
DROP INDEX index_name ON table_name
DROP INDEX BkAuAndInfoIdx ON book
SHOW CREATE TABLE book; Table Create Table ------ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- book 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_publication` year(4) NOT NULL, KEY `BkNameIdx` (`bookname`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8
可以看到,復合索引BkAuAndInfoIdx已經被刪除了
提示:刪除表中的某列時,如果要刪除的列為索引的組成部分,則該列也會從索引中刪除。
如果索引中的所有列都被刪除,則整個索引將被刪除!!
總結
這一節介紹了MYSQL中的索引,索引語句的創建和刪除和一些簡單用法,希望對大家有幫助
如有不對的地方,歡迎大家拍磚o(∩_∩)o