当前位置:网站首页>Mysql高级篇学习总结9:创建索引、删除索引、降序索引、隐藏索引
Mysql高级篇学习总结9:创建索引、删除索引、降序索引、隐藏索引
2022-07-06 04:59:00 【koping_wu】
Mysql高级篇学习总结9:创建索引、删除索引、降序索引、隐藏索引
1、索引的声明和使用
1.1 索引的分类
mysql的索引包括普通索引、唯一性索引、全文索引、单列索引、多列索引、空间索引。
- 按照功能逻辑:索引主要有4种,分别是普通索引、唯一索引、主键索引、全文索引;
- 按照物理实现方式:索引可以分为2种,聚簇索引和非聚簇索引;
- 按照作用字段个数:分成单列索引和联合索引;
1.2 创建索引
Mysql支持多种方法在单个或多个列上创建索引:
1)在创建表的定义语句CREATE TABLE中指定索引列;
2)在已存在的表上,使用ALTER TABLE语句创建索引,或者使用CREATE INDEX语句在已存在的表上添加索引;
1.2.1 创建表的时候创建索引
1.2.1.1 隐式的方式创建索引
在声明有主键约束、唯一性约束、外键约束的字段上,会自动的添加相关的索引
CREATE TABLE dept(
dept_id INT PRIMARY KEY AUTO_INCREMENT,
dept_name VARCHAR(20)
);
CREATE TABLE emp(
emp_id INT PRIMARY KEY AUTO_INCREMENT,
emp_name VARCHAR(20) UNIQUE,
dept_id INT,
CONSTRAINT emp_dept_id_fk FOREIGN KEY(dept_id) REFERENCES dept(dept_id)
);
可以通过命令查看索引:
方式1:SHOW INDEX FROM 表名;
mysql> SHOW INDEX FROM emp;
+-------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| emp | 0 | PRIMARY | 1 | emp_id | A | 0 | NULL | NULL | | BTREE | | |
| emp | 0 | emp_name | 1 | emp_name | A | 0 | NULL | NULL | YES | BTREE | | |
| emp | 1 | emp_dept_id_fk | 1 | dept_id | A | 0 | NULL | NULL | YES | BTREE | | |
+-------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
3 rows in set (0.01 sec)
可以看到主键emp_id的索引名是PRIMARY,emp_name的索引名是emp_name,dept_id的索引名是emp_dept_id_fk。
方式2:SHOW CREATE TABLE 表名;
mysql> SHOW CREATE TABLE emp;
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| emp | CREATE TABLE `emp` (
`emp_id` int(11) NOT NULL AUTO_INCREMENT,
`emp_name` varchar(20) DEFAULT NULL,
`dept_id` int(11) DEFAULT NULL,
PRIMARY KEY (`emp_id`),
UNIQUE KEY `emp_name` (`emp_name`),
KEY `emp_dept_id_fk` (`dept_id`),
CONSTRAINT `emp_dept_id_fk` FOREIGN KEY (`dept_id`) REFERENCES `dept` (`dept_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
1.2.1.2 显式的方式创建索引
1)创建普通的索引
mysql> CREATE TABLE book(
-> book_id INT ,
-> book_name VARCHAR(100),
-> AUTHORS VARCHAR(100),
-> info VARCHAR(100) ,
-> COMMENT VARCHAR(100),
-> year_publication YEAR,
-> #声明索引
-> INDEX idx_bname(book_name)
-> );
Query OK, 0 rows affected (0.21 sec)
还是可以通过show index from book来查看索引:
mysql> SHOW INDEX FROM book;
+-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| book | 1 | idx_bname | 1 | book_name | A | 0 | NULL | NULL | YES | BTREE | | |
+-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)
除此之外,还可以通过性能分析工具:EXPLAIN来查看是否使用到了索引:
mysql> EXPLAIN SELECT * FROM book WHERE book_name = 'mysql';
+----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
| 1 | SIMPLE | book | NULL | ref | idx_bname | idx_bname | 103 | const | 1 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
比如通过book_name进行检索,可以看到使用到的索引(key)是idx_bname,这就是刚刚上面建立的普通索引。
2)创建唯一索引
声明有唯一索引的字段,在添加数据时,要保证唯一性,但是可以添加null
比如,下面以注释comment作为唯一索引
CREATE TABLE book1(
book_id INT ,
book_name VARCHAR(100),
AUTHORS VARCHAR(100),
info VARCHAR(100) ,
COMMENT VARCHAR(100),
year_publication YEAR,
#声明索引
UNIQUE INDEX uk_idx_cmt(COMMENT)
);
mysql> SHOW INDEX FROM book1;
+-------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| book1 | 0 | uk_idx_cmt | 1 | COMMENT | A | 0 | NULL | NULL | YES | BTREE | | |
+-------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)
3)主键索引
通过定义主键约束的方式定义主键索引
CREATE TABLE book2(
book_id INT PRIMARY KEY ,
book_name VARCHAR(100),
AUTHORS VARCHAR(100),
info VARCHAR(100) ,
COMMENT VARCHAR(100),
year_publication YEAR
);
mysql> SHOW INDEX FROM book2;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| book2 | 0 | PRIMARY | 1 | book_id | A | 0 | NULL | NULL | | BTREE | | |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)
4)创建单列索引
CREATE TABLE book3(
book_id INT ,
book_name VARCHAR(100),
AUTHORS VARCHAR(100),
info VARCHAR(100) ,
COMMENT VARCHAR(100),
year_publication YEAR,
#声明索引
UNIQUE INDEX idx_bname(book_name)
);
5)创建联合索引
CREATE TABLE book4(
book_id INT ,
book_name VARCHAR(100),
AUTHORS VARCHAR(100),
info VARCHAR(100) ,
COMMENT VARCHAR(100),
year_publication YEAR,
#声明索引
INDEX mul_bid_bname_info(book_id,book_name,info)
);
mysql> SHOW INDEX FROM book4;
+-------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| book4 | 1 | mul_bid_bname_info | 1 | book_id | A | 0 | NULL | NULL | YES | BTREE | | |
| book4 | 1 | mul_bid_bname_info | 2 | book_name | A | 0 | NULL | NULL | YES | BTREE | | |
| book4 | 1 | mul_bid_bname_info | 3 | info | A | 0 | NULL | NULL | YES | BTREE | | |
+-------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
3 rows in set (0.00 sec)
注意,使用联合索引要遵循最左前缀原则,也就是使用索引的话至少要包含联合索引的最左边的索引才能检索。
比如下面的2条检索语句,在第2条语句中,由于直接以book_name进行检索,而联合索引的首先是以book_id进行排序检索的,它这里找不到,所以就没有成功用到我们刚刚建的联合索引了。
mysql> EXPLAIN SELECT * FROM book4 WHERE book_id = 1001 AND book_name = 'mysql';
+----+-------------+-------+------------+------+--------------------+--------------------+---------+-------------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+--------------------+--------------------+---------+-------------+------+----------+-------+
| 1 | SIMPLE | book4 | NULL | ref | mul_bid_bname_info | mul_bid_bname_info | 108 | const,const | 1 | 100.00 | NULL |
+----+-------------+-------+------------+------+--------------------+--------------------+---------+-------------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
mysql> EXPLAIN SELECT * FROM book4 WHERE book_name = 'mysql';
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | SIMPLE | book4 | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
6)创建全文索引
CREATE TABLE test4(
id INT NOT NULL,
NAME CHAR(30) NOT NULL,
age INT NOT NULL,
info VARCHAR(255),
FULLTEXT INDEX futxt_idx_info(info(50))
)
1.2.2 在已存在的表上创建索引
方式1:表已经创建好了,可以使用 **ALTER TABLE … ADD …**来添加索引。
CREATE TABLE book5(
book_id INT ,
book_name VARCHAR(100),
AUTHORS VARCHAR(100),
info VARCHAR(100) ,
COMMENT VARCHAR(100),
year_publication YEAR
);
在创建了该表后,给该表添加索引:
ALTER TABLE book5 ADD INDEX idx_cmt(COMMENT);
ALTER TABLE book5 ADD UNIQUE uk_idx_bname(book_name);
ALTER TABLE book5 ADD INDEX mul_bid_bname_info(book_id,book_name,info);
方式2:表已经创建好了,还可以使用 **CREATE INDEX … ON …**来添加索引。
CREATE TABLE book6(
book_id INT ,
book_name VARCHAR(100),
AUTHORS VARCHAR(100),
info VARCHAR(100) ,
COMMENT VARCHAR(100),
year_publication YEAR
);
CREATE INDEX idx_cmt ON book6(COMMENT);
CREATE UNIQUE INDEX uk_idx_bname ON book6(book_name);
CREATE INDEX mul_bid_bname_info ON book6(book_id,book_name,info);
1.3 删除索引
方式1:ALTER TABLE … DROP INDEX …
ALTER TABLE book5 DROP INDEX idx_cmt;
方式2:DROP INDEX … ON …
DROP INDEX uk_idx_bname ON book5;
注意:删除表中的列时,如果要删除的列为索引的组成部分,则该列也会从索引中删除。如果组成索引的所有列都被删除,则整个索引将被删除。
2、Mysql8.0索引新特性
2.1 支持降序索引
Mysql在8.0版本之前创建的是升序索引,使用时进行反向扫描,这大大降低了数据库的效率。
比如创建表ts1:
CREATE TABLE ts1(a INT,b INT,INDEX idx_a_b(a ASC,b DESC));
如果是经常使用b的降序进行检索,那么8.0版本可以成功使用索引,大大降低数据库检索时间。而8.0之前的版本,由于没有这个降序索引的特性,所以检索时间更长。
EXPLAIN SELECT * FROM ts1 ORDER BY a,b DESC LIMIT 5;
2.2 隐藏索引
有的时候,我们不确定索引是否有效,或者想验证下删除索引是否会造成什么影响,可以不直接删除索引,可以先隐藏索引。
从Mysql8.0开始支持隐藏索引(invisible indexes),只需要将待删除的索引设置为隐藏索引,使查询优化器不再使用这个索引。等确认将索引设置为隐藏索引后,系统不会造成任何影响,就可以彻底删除该索引。
隐藏索引的方式,也分为创建表时,和创建表后:
方式1:创建表时,隐藏索引
CREATE TABLE book7(
book_id INT ,
book_name VARCHAR(100),
AUTHORS VARCHAR(100),
info VARCHAR(100) ,
COMMENT VARCHAR(100),
year_publication YEAR,
#创建不可见的索引
INDEX idx_cmt(COMMENT) invisible
);
方式2:创建表以后,隐藏索引
ALTER TABLE book7
ADD UNIQUE INDEX uk_idx_bname(book_name) invisible;
还可以修改索引的可见性:
比如将索引idx_cmt由不可见改为可见:
ALTER TABLE book7 ALTER INDEX idx_cmt visible;
然后再将索引idx_cmt由可见改为不可见:
ALTER TABLE book7 ALTER INDEX idx_cmt invisible;
边栏推荐
- 关于es8316的音频爆破音的解决
- 2021 robocom world robot developer competition - undergraduate group (semi-finals)
- Bill Gates posted his 18-year-old resume and expected an annual salary of $12000 48 years ago
- RT thread analysis - object container implementation and function
- DMA use of stm32
- [NOIP2009 普及组] 分数线划定
- Chip debugging of es8316 of imx8mp
- Project manager, can you draw prototypes? Does the project manager need to do product design?
- 【LGR-109】洛谷 5 月月赛 II & Windy Round 6
- Postman关联
猜你喜欢
Crazy God said redis notes
行业专网对比公网,优势在哪儿?能满足什么特定要求?
MPLS experiment
ISP学习(2)
L'introduction en bourse de MSK Electronics a pris fin: 800 millions de RMB d'actifs de Henan étaient des actionnaires
Pagoda configuration mongodb
Vite configures the development environment and production environment
RTP gb28181 document testing tool
Basic knowledge and examples of binary tree
Golang -- TCP implements concurrency (server and client)
随机推荐
What should the project manager do if there is something wrong with team collaboration?
Class inheritance in yyds dry inventory C
Uva1592 Database
win10电脑系统里的视频不显示缩略图
Redis 排查大 key 的4種方法,優化必備
EditorUtility.SetDirty在Untiy中的作用以及应用
Weng Kai C language third week 3.1 punch in
Fiddler installed the certificate, or prompted that the certificate is invalid
yolov5 tensorrt加速
2021robocom robot developer competition (Preliminary)
GAMES202-WebGL中shader的編譯和連接(了解向)
Scala function advanced
Leetcode dynamic planning day 16
图论的扩展
It is also a small summary in learning
Postman关联
Three.js学习-光照和阴影(了解向)
Hometown 20 years later (primary school exercises)
RTP gb28181 document testing tool
Drive development - the first helloddk