Mysql Advanced Learning Summary 9: Create Index, Delete Index, Descending Index, Hidden Index

1. Declaration and use of indexes

1.1 Classification of Indexes

MySQL indexes include ordinary indexes, unique indexes, full-text indexes, single-column indexes, multi-column indexes, and spatial indexes.

  • According to the functional logic : there are mainly four types of indexes, namely ordinary indexes, unique indexes, primary key indexes, and full-text indexes;
  • According to the physical implementation method : the index can be divided into two types, clustered index and non-clustered index;
  • According to the number of functional fields : divided into single-column index and joint index;

1.2 Create an index

Mysql supports multiple methods to create indexes on single or multiple columns:
1) Specify the index column in the definition statement CREATE TABLE of creating a table;
2) On an existing table, use the ALTER TABLE statement to create an index, or use CREATE INDEX The statement adds an index to an existing table;

1.2.1 Create an index when creating a table

1.2.1.1 Create indexes implicitly

On fields declared with primary key constraints, unique constraints, and foreign key constraints, related indexes will be automatically added

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)
);

You can view the index through the command :
Mode 1: SHOW INDEX FROM table name ;

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)

You can see that the index name of the primary key emp_id is PRIMARY, the index name of emp_name is emp_name, and the index name of dept_id is emp_dept_id_fk.

Method 2: SHOW CREATE TABLE table name ;

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 Explicitly create indexes

1) Create a normal index

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)

You can still view the index through 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)

In addition, you can also use the performance analysis tool: EXPLAIN to check whether the index is used :

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)

For example, if you search through book_name, you can see that the index (key) used is idx_bname, which is the ordinary index just created above.

2) Create a unique index
Declare a field with a unique index. When adding data, you must ensure uniqueness, but you can add null.
For example, the comment below is used as the unique index

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) Primary key index
Define the primary key index by defining the primary key constraint

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 a single-column index

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 a joint index

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)

Note that the use of a joint index must follow the leftmost prefix principle , that is, if an index is used, it must contain at least the leftmost index of the joint index to retrieve .

For example, in the following two search statements, in the second statement, because the book_name is directly used for searching, and the joint index is first sorted and searched by book_id, it cannot be found here, so it is not successfully used. of the joint index.

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 a full-text index

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 Create an index on an existing table

Method 1: The table has been created, you can use **ALTER TABLE ... ADD ...** to add indexes .

CREATE TABLE book5(
book_id INT ,
book_name VARCHAR(100),
AUTHORS VARCHAR(100),
info VARCHAR(100) ,
COMMENT VARCHAR(100),
year_publication YEAR
);

After creating the table, add an index to the table:

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);

Method 2: The table has been created, and you can also use **CREATE INDEX ... ON ...** to add indexes .

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 Delete index

Method 1: ALTER TABLE ... DROP INDEX ...

ALTER TABLE book5 DROP INDEX idx_cmt;

Method 2: DROP INDEX ... ON ...

DROP INDEX uk_idx_bname ON book5;

Note: When dropping a column in a table, if the column being dropped is part of an index, that column is also dropped from the index. If all the columns that make up the index are dropped, the entire index will be dropped.

2. New features of Mysql8.0 index

2.1 Support descending index

Mysql created an ascending index before version 8.0, and reversed scanning was performed when using it, which greatly reduced the efficiency of the database .

For example, create table ts1:

CREATE TABLE ts1(a INT,b INT,INDEX idx_a_b(a ASC,b DESC));

If the descending order of b is often used for retrieval, then the 8.0 version can successfully use the index, which greatly reduces the database retrieval time. The version before 8.0, because there is no feature of this descending index, so the retrieval time is longer.

EXPLAIN SELECT * FROM ts1 ORDER BY a,b DESC LIMIT 5;

2.2 Hidden Index

Sometimes, we are not sure whether the index is valid, or want to verify whether deleting the index will cause any impact, we can hide the index first instead of deleting the index directly.

Since Mysql8.0 supports hidden indexes (invisible indexes), you only need to set the index to be deleted as a hidden index, so that the query optimizer will no longer use this index . After confirming that setting the index as a hidden index will not cause any impact on the system, you can completely delete the index.

The way to hide the index is also divided into when creating the table and after creating the table:
Method 1: when creating the table, hide the index

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
);

Method 2: After creating the table, hide the index

ALTER TABLE book7
ADD UNIQUE INDEX uk_idx_bname(book_name) invisible;

You can also modify the visibility of the index :
for example, change the index idx_cmt from invisible to visible:

ALTER TABLE book7 ALTER INDEX idx_cmt visible; 

Then change the index idx_cmt from visible to invisible:

ALTER TABLE book7 ALTER INDEX idx_cmt invisible; 

Guess you like

Origin blog.csdn.net/xueping_wu/article/details/125583631