目录
一、索引适合、不适合的场所
以下情况适合创建索引
- 经常被查询的字段,即在 WHERE 字句中出现的字段
- 在分组的字段,即在 GROUP BY 字句中出现的字段
- 存在依赖关系的子表和父表之间的联合查询,即主键和外键字段
- 设置唯一完整性约束的字段。
在以下情况下不适合创建索引:
- 在查询中很少被使用的字段
- 拥有许多重复值的字段
二、创建和查看索引
- 创建表时创建索引
- 在已经存在的表上创建索引
- 通过 SQL 语句 ALTER TABLE 创建索引
1、创建和查看普通索引
1.1创建表时创建普通索引
语法形式:
CREATE TABLE table_name (
属性名 数据类型,
属性名 数据类型,
…… ……
属性名 数据类型,
INDEX|KEY 【索引名】(属性名1 【(长度)】 【ASC|DESC】)
);
ASC ----- 升序
DESC ----- 降序
例:建立表 并创建名为 index_deptono 索引,其所关联的字段为deptno
mysql> CREATE TABLE t_dept(
-> deptno INT,
-> dname VARCHAR(20),
-> loc VARCHAR(40),
-> INDEX index_deptno(deptno)
-> );
Query OK, 0 rows affected (0.02 sec)
检验:效验表t_dept中索引是否创建成功
mysql> SHOW CREATE TABLE t_dept \G
*************************** 1. row ***************************
Table: t_dept
Create Table: CREATE TABLE `t_dept` (
`deptno` int DEFAULT NULL,
`dname` varchar(20) DEFAULT NULL,
`loc` varchar(40) DEFAULT NULL,
KEY `index_deptno` (`deptno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3
1 row in set (0.00 sec)
结果中“ KEY index_deptno
(deptno
)”显示已经创建了名为“index_deptno”的索引,其所关联的字段为 deptno
检验:效验索引是否被启用
语法形式:EXPLAIN 1
EXPLAIN
SELECT * FROM t_dept WHERE deptno=1 \G
mysql> EXPLAIN
-> SELECT *FROM t_dept WHERE deptno=1\G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t_dept
partitions: NULL
type: ref
possible_keys: index_deptno
key: index_deptno
key_len: 5
ref: const
rows: 1
filtered: 100.00
Extra: NULL
1 row in set, 1 warning (0.02 sec)
ERROR:
No query specified
possible_keys 与 key项中值都为所创建的索引名 index_deptno,说明该索引已经存在而且已经开始启用。
写到这里,细心的朋友会看到我上面的运行结果中有1个waring和1个ERROR
首先看一下警告是什么,运行SHOW WARNINGS;
mysql> SHOW WARNINGS;
+-------+------+----------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------+
| Level | Code | Message
|
+-------+------+----------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------+
| Note | 1003 | /* select#1 */ select `company`.`t_dept`.`deptno` AS `deptno`,`
company`.`t_dept`.`dname` AS `dname`,`company`.`t_dept`.`loc` AS `loc` from `com
pany`.`t_dept` where (0 <> (`company`.`t_dept`.`deptno` + 1)) |
+-------+------+----------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------+
1 row in set (0.00 sec)
针对这个问题我在咱们网站求救高人,正在等待回复,等有了结果再更新。当然如果有人知道不妨在评论中直接告诉我。
至于那个ERROR,我已经找到答案,就是
EXPLAIN
SELECT *FROM t_dept WHERE deptno=1\G;
语句末尾处我多了个分号“ ; ”。
G 与 ;都是结束符,当执行到第二个结束符(;)时,由于 G 与 ; 中间没有语句,系统认为是没有指定查询或是空查询,所以报No query specified(没有指定查询)错误。
详细请看No query specified解决办法
1.2在已经存在的表上创建普通索引
语法形式:
CREATE INDEX 索引名
ON 表名 (属性名 【(长度)】 【ASC|DESC】)
例:在表t_dept 中建立以index_deptno为索引名的索引,其关联的字段为 deptno
mysql> CREATE INDEX index_deptno
-> ON t_dept(deptno);
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
检验:略
1.3通过SQL 语句 ALTER TABLE 创建普通索引
语法:
ALTER TABLE table_name
ADD INDEX|KEY 索引名(属性名【(长度)】【ASC|DESC】)
上述的语句中,INDEX 或 KEY 关键字用来指定创建普通索引,属性名-----索引所关联的字段,长度-----索引的长度 ,ASC ----- 升序排序,DESC ------ 降序排序
例:在表 t_dept 中添加索引名为 index_deptno 的索引,其关联的字段为 deptno
mysql> ALTER TABLE t_dept
-> ADD INDEX index_deptno(deptno);
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
检验: 略
2、创建和查看唯一索引
唯一索引:
在创建索引是,限制索引的值必须是唯一的。优势为通过该类型的索引可以更快的查询某条记录。分为自动索引和手动索引
自动索引
在数据库表里设置完整性约束时,该表会被系统自动创建索引。当设置表中的某个字段设置主键或唯一完整性约束时,系统就会自动创建关联该字段的唯一索引。
手动索引
手动在表上创建索引。
2.1创建表时创建唯一索引
语法形式
CREATE TABLE table_name(
属性名 数据类型
属性名 数据类型
…………
属性名 数据类型
UNIQUE INDEX|KEY 【索引名】(属性名1 【(长度)】 【ASC|DESC】)
);
例:
创建表名为 t_dept 的表,同时指定字段 deptno 为唯一索引,索引名为 index_deptno
mysql> CREATE TABLE t_dept(
-> deptno INT,
-> dname VARCHAR(20),
-> loc VARCHAR(40),
-> UNIQUE INDEX index_deptno(deptno)
-> );
Query OK, 0 rows affected (0.02 sec)
验证: 略
2.2在已经存在的表上创建唯一索引
语法形式
CREATE UNIQUE INDEX 索引名
ON 表名(属性名 【(长度)】 【ASC|DESC】);
例:
在表 t_dept 中,指定字段 deptno 为唯一索引,索引名为 index_deptno
mysql> CREATE UNIQUE INDEX index_deptno
-> ON t_dept(deptno);
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
2.3通过SQL语句ALTER TABLE创建唯一索引
语法形式:
ALTER TABLE table_name
ADD UNIQUE INDEX|KEY 索引名(属性名 【(长度)】 【ASC|DESC】);
例:
创建关联表 t_dept 中字段 deptno 的唯一索引 index_deptno
mysql> ALTER TABLE t_dept
-> ADD UNIQUE INDEX index_deptno(deptno);
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
3、创建和查看全文索引
全文索引主要关联在数据类型为 CHAR、VARCHA 和 TEXT的字段上,以便能够更加快速地查询数据量较大的字符串类型的字段。只能在存储引擎为 MyISAM 数据库表上创建全文索引。
3.1创建表时创建全文索引
语法形式:
CREATE TABLE table_name(
属性名 数据类型
属性名 数据类型
…………
属性名 数据类型
FULLTEXT INDEX|KEY 【索引名】(属性名1 【(长度)】 【ASC|DESC】)
);
例:
在创建表 t_dept 时,在字段 loc 上创建全文索引
并把数据引擎改为 MyISAM
mysql> CREATE TABLE t_dept(
-> deptno INT,
-> dname VARCHAR(20),
-> loc VARCHAR(40),
-> FULLTEXT INDEX index_loc(loc)
-> ) ENGINE=MyISAM;
Query OK, 0 rows affected (0.01 sec)
效验:
mysql> SHOW CREATE TABLE t_dept \G
*************************** 1. row ***************************
Table: t_dept
Create Table: CREATE TABLE `t_dept` (
`deptno` int DEFAULT NULL,
`dname` varchar(20) DEFAULT NULL,
`loc` varchar(40) DEFAULT NULL,
FULLTEXT KEY `index_loc` (`loc`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb3
1 row in set (0.01 sec)
3.2在已经存在的表上创建全文索引
语法形式:
CREATE FULLTEXT INDEX 索引名
ON 表名(属性名1 【(长度)】 【ASC|DESC】)
例: 创建关联表 t_dept 中字段 loc 的全文索引 index_loc
mysql> CREATE FULLTEXT INDEX index_loc
-> ON t_dept(loc);
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
检验: 略
3.3通过SQL语句ALTER TABLE创建全文索引
语法形式:
ALTER TABLE table_name
ADD FULLTEXT INDEX|KEY 索引名(属性名1 【(长度)】 【ASC|DESC】);
例: 用 ALTER TABLE 关联表 t_dept 中字段 loc 的全文索引 index_loc
mysql> ALTER TABLE t_dept
-> ADD FULLTEXT INDEX index_loc(loc);
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
检验: 略
4 创建和查看多列索引
多列索引: 创建索引时,所关联的字段为多个字段。
注意: 虽然可以通过所关联的字段进行查询,但只有查询条件中使用了所关联字段中第一个字段,多列索引才会被使用
4.1 创建表时创建多列索引
语法形式:
CREATE TABLE talble_name(
属性名 数据类型,
…………
属性名 数据类型,
INDEX|KEY 【索引名】(属性名1 【(长度)】 【ASC|DESC】,
…………
属性名1 【(长度)】 【ASC|DESC】)
);
例: 创建表 t_dept 时,创建名为 index_dname_loc 的多列索引 ,所关联的字段为 dname 和 loc
mysql> CREATE TABLE t_dept(
-> deptno INT,
-> dname VARCHAR(20),
-> loc VARCHAR(40),
-> INDEX index_dname_loc(dname,loc)
-> );
Query OK, 0 rows affected (0.06 sec)
检验: 略
4.2 在已存在的表上创建多列索引
语法形式:
CREATE INDEX 索引名
ON 表名(属性名1 【(长度)】 【ASC|DESC】),
…………
(属性名1 【(长度)】 【ASC|DESC】);
例: 在表 t_dept 中创建名为 index_dname_loc 的多列索引,其所关联的字段为 dname 和 loc
mysql> CREATE INDEX index_dname_loc
-> ON t_dept (dname,loc);
Query OK, 0 rows affected (0.24 sec)
Records: 0 Duplicates: 0 Warnings: 0
检验: 略
4.3 通过 SQL 语句 ALTER TABLE 创建多列索引
语法形式:
ALTER TABLE table_name
ADD INDEX|KEY 【索引名】(属性名1 【(长度)】 【ASC|DESC】,
…………
属性名1 【(长度)】 【ASC|DESC】);
例: 在表 t_dept 中创建名为 index_dname_loc 的多列索引,其所关联的字段为 dname 和 loc
mysql> ALTER TABLE t_dept
-> ADD INDEX index_dname_loc(dname,loc);
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
检验: 略
三、删除索引
语法形式:
DROP INDEX index_name
ON table_name;
例: 在表 t_dept 中删除索引名为 index_dname_loc 的索引
1、查询表 t_dept 中是否存在索引
mysql> SHOW CREATE TABLE t_dept \G
*************************** 1. row ***************************
Table: t_dept
Create Table: CREATE TABLE `t_dept` (
`deptno` int DEFAULT NULL,
`dname` varchar(20) DEFAULT NULL,
`loc` varchar(40) DEFAULT NULL,
KEY `index_dname_loc` (`dname`,`loc`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3
1 row in set (0.00 sec)
从查询结果中可以看到:
KEY `index_dname_loc` (`dname`,`loc`)
在表 t_dept 中存在名为 index_dname_loc 多列索引,其关联的字段为 dname 和 loc
2、删除表 t_dept 中名为 index_dname_loc 的多列索引
mysql> DROP INDEX index_dname_loc
-> ON t_dept;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
3、再次查询表 t_dept 中是否存在索引
mysql> SHOW CREATE TABLE t_dept \G
*************************** 1. row ***************************
Table: t_dept
Create Table: CREATE TABLE `t_dept` (
`deptno` int DEFAULT NULL,
`dname` varchar(20) DEFAULT NULL,
`loc` varchar(40) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3
1 row in set (0.00 sec)
从查询结果中可以看出表 t_dept 已经没有索引了
生词表
单词 | 读音 | 译文 | MySQL |
---|---|---|---|
Ascending | 英 [əˈsendɪŋ] | adj.(次序)上升的,渐进的 | 升序 ASC |
Descending | 英 [dɪˈsendɪŋ] | 下降;递减;下来;降序;下行 | 降序 DESC |
Explain | 英 [ɪkˈspleɪn] | v.解释;说明;阐明;说明(…的)原因;解释(…的)理由 | 查询 |
Unique | 英 [juˈniːk] | adj.唯一的;独一无二的; | 唯一 |
如有错误敬请高人指点,书写的易读性可否,希望大家多提意见。
码字不易,留下足迹再走吧(@)_(@)
详情请看链接: 《SQL学习(九):Explain详解》. ↩︎