当前位置:网站首页>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;
边栏推荐
猜你喜欢
JS quick start (II)
What are the advantages of the industry private network over the public network? What specific requirements can be met?
Ue5 small knowledge points to enable the setting of lumen
麥斯克電子IPO被終止:曾擬募資8億 河南資產是股東
Fiddler installed the certificate, or prompted that the certificate is invalid
Vite configures the development environment and production environment
[05-1, 05-02, 05-03] network protocol
Sqlserver query results are not displayed in tabular form. How to modify them
Cve-2019-11043 (PHP Remote Code Execution Vulnerability)
比尔·盖茨晒18岁个人简历,48年前期望年薪1.2万美元
随机推荐
【LGR-109】洛谷 5 月月赛 II & Windy Round 6
[NOIP2009 普及组] 分数线划定
Rce code and Command Execution Vulnerability
Oracle deletes duplicate data, leaving only one
Project manager, can you draw prototypes? Does the project manager need to do product design?
RTP GB28181 文件测试工具
2021RoboCom机器人开发者大赛(初赛)
Delete subsequence < daily question >
Bill Gates posted his 18-year-old resume and expected an annual salary of $12000 48 years ago
几种RS485隔离通讯的方案介绍
IPv6 comprehensive experiment
[buuctf.reverse] 159_ [watevrCTF 2019]Watshell
麦斯克电子IPO被终止:曾拟募资8亿 河南资产是股东
idea一键导包
关于Unity Inspector上的一些常用技巧,一般用于编辑器扩展或者其他
Ue5 small knowledge points to enable the setting of lumen
2021 robocom world robot developer competition - undergraduate group (semi-finals)
Weng Kai C language third week 3.1 punch in
2021 RoboCom 世界机器人开发者大赛-本科组(复赛)
[noip2009 popularization group] score line delimitation