0
点赞
收藏
分享

微信扫一扫

【MySQL 索引的操作】

老王420 2022-04-15 阅读 41

目录

一、索引适合、不适合的场所

以下情况适合创建索引

  • 经常被查询的字段,即在 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.唯一的;独一无二的;唯一

如有错误敬请高人指点,书写的易读性可否,希望大家多提意见。
码字不易,留下足迹再走吧(@)_(@)


  1. 详情请看链接: 《SQL学习(九):Explain详解》. ↩︎

举报

相关推荐

0 条评论