在MySQL中,如果我们要在一个表中找到一条记录,那么就要从第一个表开始查找,直到找到该记录、或者遍历整个表,然后返回空,表示该表没有该记录,非常浪费时间,而索引就是用于快速找出在某个列中有意特定值的行,也就是记录。
索引简介
索引的含义和特点
索引是一个单独的、存储在磁盘上的数据库结构,包含着对数据表里所有记录的引用指针,使用它可以快速定位到特定的列或行,所有MySQL的类型都可以被索引,并且对相关列使用索引是提高查询操作速度的最佳途径。
索引的优点:
- 通过创建索引,可以保证数据库表中的每一行数据的唯一性。
- 可以大大加快数据的查询速度,这也是床创建索引的主要原因。
- 在实现数据参考完整性方面,可以加速表和表之间的连接。
- 在使用分组和排序子句进行数据查询时,也可以显著减少查询中分组和排序的时间。
缺点:
- 创建和维护索引要耗费时间。
- 索引需要占用磁盘空间。
- 对表进行各种操作时,索引也要动态的维护,这就降低了数据的维护速度。
索引的分类
- 普通索引和唯一索引
普通索引:是MySQL中的基本索引类型,允许在定义索引的列中插入空值和重复值
唯一索引:要求索引所在列中的值都是唯一的,但允许有空值 - 单列索引和组合索引
单列索引:是一个索引包含单个列,自然一个表可以有多个单列索引
组合索引:多个字段的索引,只有使用了其中的列,索引才会被使用,且组合中必须包含有第一列,才能使用索引。 - 全文索引
全文索引类型为:FULLTEXT,在定义索引的列上支持值的全文查找,并允许插入重复值和空值,可在CHAR、VARCHAR、TEXT类型上创建。MySQL中只有MyISAM存储引擎支持全文索引。索引总是对整个列进行,不支持局部(前缀)索引。 - 空间索引
空间索引是对空间数据类型的字段建立的索引,MySQL中的空间数据类型有:GEOMETRY、POINT、LINESTRING和POLYGON。MySQL使用SOPATIAL关键字进行扩展,使用能够创建正规索引类似的语法创建空间索引。创建空间索引的列,必须声明为NOT NULL,空间索引只能在存储引擎为MyISAM的表中创建。
索引的设计原则
- 索引并非越多越好,一个表中有大量索引,会占用大量的磁盘空间,对INSERT、DELETE、UPDATE等这些更改数据的语句的性能有影响,因为在更改数据时,索引也要动态的更改。
- 对经常更改数据的表要尽量避免大量索引,索引内的列也要尽量的少。应该对经常用于查询的表常见索引,索引可能不会产生优化的效果。
- 数据量少的表,不建议创建索引,因为索引的空间可能比存储表和数据的空间要大,且遍历一次表的速度也可能比使用索引快。
- 对列中有不同值较多的列使用索引,而相同值多的列则不建议使用索引。
- 当数据有唯一性,那么索引必须也是唯一的。
- 在频繁进行排序和分组的列上建立索引,如果有多个列就建立组合索引。
创建索引
MySQL支持多种方法在单列或多列上创建索引;在创建表的定义语句上CREATE TABLE 中指定索引列,使用ALTER TABLE语句已创建的表中添加索引,或者使用CREATE INDEX语句在已存在的表中添加索引,主要介绍以上三种方法。
创建表时创建索引
语法格式:CREATE TABLE table_name [col_name data_type] [UNIQUE | FULLTEXT | SPATIAL] [INDEX | KEY] [index_name] (col_name [length]) [ASC | DESC]
//详解:
//table_name [col_name data_type]: 就是创建列的数据及其数据类型;
//[UNIQUE | FULLTEXT | SPATIAL]:可选,分别是唯一索引,全文索引和空间索引;
//[INDEX | KEY]:两个此时同义词,都是一样的作用,用来指定创建索引;
//[index_name]:索引名称,若不写,则默认为列或数据的名称;
//(col_name [length]):索引值及其长度,长度为可选参数;
//[ASC | DESC]:正序和倒序显示。
- 创建普通索引
最基本的索引,没有唯一性之类的要求,其作用只是加快对数据的访问速度。
mysql> CREATE TABLE book
-> (
-> bookid INT NOT NULL,
-> bookname VARCHAR(255) NOT NULL,
-> authors VARCHAR(255) NOT NULL,
-> info VARCHAR(255) NULL,
-> comment VARCHAR(255) NULL,
-> year_publication YEAR NOT NULL,
-> INDEX(year_publication)
-> );
Query OK, 0 rows affected (0.15 sec)
//查看表的详细情况,可以看到索引的名称默认为字段的名称
mysql> SHOW CREATE table book\g
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| book | CREATE TABLE `book` (
`bookid` int(11) NOT NULL,
`bookname` varchar(255) NOT NULL,
`authors` varchar(255) NOT NULL,
`info` varchar(255) DEFAULT NULL,
`comment` varchar(255) DEFAULT NULL,
`year_publication` year(4) NOT NULL,
KEY `year_publication` (`year_publication`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
//使用EXPLAIN语句查看索引是否正在使用:
mysql> EXPLAIN SELECT * FROM book WHERE year_publication=1990 \g
+----+-------------+-------+------------+------+------------------+------------------+---------+-------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+------------------+------------------+---------+-------+------+----------+-----------------------+
| 1 | SIMPLE | book | NULL | ref | year_publication | year_publication | 1 | const | 1 | 100.00 | Using index condition |
+----+-------------+-------+------------+------+------------------+------------------+---------+-------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
//我们详细看看这几个EXPLAIN的参数的含义:
//select_ type行指定所使用的 SELECT查询类型,这里值为SIMPLE,表示简单的 SELECT,不使用 UNION或子查询。其他可能的取值有PRIMARY、UNION、SUBQUERY 等.
//table行指定数据库读取的数据表的名字,它们按被读取的先后顺序排列。
//type行指定了本数据表与其他数据表之间的关联关系,可能的取值有 system、const、eq_ref、 ref、 range、 index和 all。
//possible_keys行给出了MySQL在搜索数据记录时可选用的各个索引。
//key行是MySQL 实际选用的索引。
//key_len行给出索引按字节计算的长度,key_len数值越小,表示越快。
//ref行给出了关联关系中另一个数据表里的数据列名。
//rows行是MySQL在执行这个查询时预计会从这个数据表里读出的数据行的个数。
//Extra行提供了与关联操作有关的信息。
//可以看到,possible kevs和 kev的值都为 year publication,查询时使用了索引。
- 创建唯一索引
mysql> CREATE TABLE t1
-> (
-> id INT NOT NULL,
-> name CHAR(30) NOT NULL,
-> UNIQUE INDEX UniqIdx(id)
-> );
Query OK, 0 rows affected (0.21 sec)
mysql> SHOW CREATE table t1 \g
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t1 | CREATE TABLE `t1` (
`id` int(11) NOT NULL,
`name` char(30) NOT NULL,
UNIQUE KEY `UniqIdx` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
mysql> EXPLAIN SELECT * FROM t1 WHERE id = 1234562 \g
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | no matching row in const table |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
1 row in set, 1 warning (0.00 sec)
- 创建单列索引
mysql> CREATE TABLE t2
-> (
-> id INT NOT NULL,
-> name CHAR(30) NULL,
-> INDEX SingleIdx(name(20))
-> );
Query OK, 0 rows affected (0.13 sec)
// 索引名称为SingleIdx,索引列为name,长度为20
mysql> SHOW CREATE table t2 \g
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t2 | CREATE TABLE `t2` (
`id` int(11) NOT NULL,
`name` char(30) DEFAULT NULL,
KEY `SingleIdx` (`name`(20))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> EXPLAIN SELECT * FROM t2 WHERE name="ysh";
+----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+-------------+
| 1 | SIMPLE | t2 | NULL | ref | SingleIdx | SingleIdx | 81 | const | 1 | 100.00 | Using where |
+----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
- 创建组合索引
mysql> CREATE TABLE t3
-> (
-> id INT(11) NOT NULL,
-> name CHAR(30) NOT NULL,
-> age INT(11) NOT NULL,
-> info VARCHAR(255),
-> INDEX MultiIdx(id, name, age)
-> );
Query OK, 0 rows affected (0.15 sec)
mysql> SHOW CREATE table t3 \G
*************************** 1. row ***************************
Table: t3
Create Table: CREATE TABLE `t3` (
`id` int(11) NOT NULL,
`name` char(30) NOT NULL,
`age` int(11) NOT NULL,
`info` varchar(255) DEFAULT NULL,
KEY `MultiIdx` (`id`,`name`,`age`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
//使用组合索引时,要注意必须要有第一个列,这里就是必须有id这个列,可以组成id = 1 AND name = 'ysh'
//也可以 id = 1 AND age = 10 ,也可以有三个,但是不能没有id,如 name = 'ysh' AND age = 11的组合,
//这样就不能触发索引,也就是说,这样的组合是不能使用索引的。
//没有id就不满足列集的最左前缀的要求,就是要有最左的列。
mysql> EXPLAIN SELECT * FROM t3 WHERE id = 1 AND name = 'ysh' \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t3
partitions: NULL
type: ref
possible_keys: MultiIdx
key: MultiIdx
key_len: 124
ref: const,const
rows: 1
filtered: 100.00
Extra: NULL
1 row in set, 1 warning (0.00 sec)
- 创建全文索引
mysql> CREATE TABLE t4
-> (
-> id INT NOT NULL,
-> name CHAR(30) NOT NULL,
-> age INT NOT NULL,
-> info VARCHAR(255),
-> FULLTEXT INDEX FullTxtIdx(info)
-> ) ENGINE=MyISAM;
Query OK, 0 rows affected (0.05 sec)
mysql> SHOW CREATE table t4 \G
*************************** 1. row ***************************
Table: t4
Create Table: CREATE TABLE `t4` (
`id` int(11) NOT NULL,
`name` char(30) NOT NULL,
`age` int(11) NOT NULL,
`info` varchar(255) DEFAULT NULL,
FULLTEXT KEY `FullTxtIdx` (`info`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.01 sec)
- 创建空间索引
mysql> CREATE TABLE t5
-> (
-> g GEOMETRY NOT NULL,
-> SPATIAL INDEX spatIdx(g)
-> )ENGINE=MyISAM;
Query OK, 0 rows affected, 1 warning (0.03 sec)
mysql> SHOW CREATE TABLE t5 \G
*************************** 1. row ***************************
Table: t5
Create Table: CREATE TABLE `t5` (
`g` geometry NOT NULL,
SPATIAL KEY `spatIdx` (`g`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
在已经存在的表上创建索引
- 使用ALTER TABLE 语句创建索引
语法格式:ALTER TABLE table_name [col_name data_type] ADD [UNIQUE | FULLTEXT | SPATIAL] [INDEX | KEY] [index_name] (col_name [length]) [ASC | DESC]
//在book中的bookname字段上建立名为BkNameIdx的普通索引
mysql> SHOW INDEX FROM book \G
*************************** 1. row ***************************
Table: book
Non_unique: 1
Key_name: year_publication
Seq_in_index: 1
Column_name: year_publication
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
1 row in set (0.06 sec)
//其中各个主要参数的含义为:
//(1) Table表示创建索引的表。
//(2) Non_unique 表示索引非唯一,1 代表是非唯一索引, 0代表唯一索引。
//(3) Key_name 表示索引的名称。
//(4) Seq_in_index 表示该字段在索引中的位置,单列索引该值为1, 组合索引为每个字段在索引定义中的顺序
//(5) Column_name表示定义索引的列字段。
//(6) Sub_part 表示索引的长度。
//(7) Null 表示该字段是否能为空值。
//(8) Index type 表示索引类型。
//可以看到,book 表中已经存在了一个索引, 即前面已经定义的名称为year_publication 索引,该索引为非唯一索引。
//增加索引
mysql> ALTER TABLE book ADD INDEX BkNameIdx(bookname(30));
Query OK, 0 rows affected (0.09 sec)
Records: 0 Duplicates: 0 Warnings: 0
//查看表中的索引
mysql> SHOW INDEX FROM book \G
*************************** 1. row ***************************
Table: book
Non_unique: 1
Key_name: year_publication
Seq_in_index: 1
Column_name: year_publication
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
*************************** 2. row ***************************
Table: book
Non_unique: 1
Key_name: BkNameIdx
Seq_in_index: 1
Column_name: bookname
Collation: A
Cardinality: 0
Sub_part: 30
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
2 rows in set (0.01 sec)
//建立一个唯一索引
mysql> ALTER TABLE book ADD UNIQUE INDEX UniquidIdx (bookId);
Query OK, 0 rows affected (0.25 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> SHOW INDEX FROM book \G
*************************** 1. row ***************************
Table: book
Non_unique: 0
Key_name: UniquidIdx
Seq_in_index: 1
Column_name: bookid
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
*************************** 2. row ***************************
Table: book
Non_unique: 1
Key_name: year_publication
Seq_in_index: 1
Column_name: year_publication
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
*************************** 3. row ***************************
Table: book
Non_unique: 1
Key_name: BkNameIdx
Seq_in_index: 1
Column_name: bookname
Collation: A
Cardinality: 0
Sub_part: 30
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
3 rows in set (0.07 sec)
//建立单列索引
mysql> ALTER TABLE book ADD INDEX BkcmtIdx(comment(50));
Query OK, 0 rows affected (0.08 sec)
Records: 0 Duplicates: 0 Warnings: 0
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 | Visible |
+-------+------------+------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+
| book | 0 | UniquidIdx | 1 | bookid | A | 0 | NULL | NULL | | BTREE | | | YES |
| book | 1 | year_publication | 1 | year_publication | A | 0 | NULL | NULL | | BTREE | | | YES |
| book | 1 | BkNameIdx | 1 | bookname | A | 0 | 30 | NULL | | BTREE | | | YES |
| book | 1 | BkcmtIdx | 1 | comment | A | 0 | 50 | NULL | YES | BTREE | | | YES |
+-------+------------+------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+
4 rows in set (0.02 sec)
//组合索引
mysql> ALTER TABLE book ADD INDEX BkAuAndInfoIdx(authors(30),info(50));
Query OK, 0 rows affected (0.08 sec)
Records: 0 Duplicates: 0 Warnings: 0
//我们看到Seq_in_index: 的值有1和2,就是在组合索引定义时列的位置。
mysql> SHOW INDEX FROM book \G
*************************** 5. row ***************************
Table: book
Non_unique: 1
Key_name: BkAuAndInfoIdx
Seq_in_index: 1
Column_name: authors
Collation: A
Cardinality: 0
Sub_part: 30
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
*************************** 6. row ***************************
Table: book
Non_unique: 1
Key_name: BkAuAndInfoIdx
Seq_in_index: 2
Column_name: info
Collation: A
Cardinality: 0
Sub_part: 50
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
6 rows in set (0.00 sec)
//添加全文索引,需要MyISAM引擎,因此重新建立了一个表
mysql> CREATE TABLE t6
-> (
-> id INT NOT NULL,
-> info CHAR(255)
-> )ENGINE=MyISAM;
Query OK, 0 rows affected (0.10 sec)
mysql> ALTER TABLE t6 ADD FULLTEXT INDEX infoFTIdx(info);
Query OK, 0 rows affected (0.13 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> SHOW INDEX FROM t6 \G
*************************** 1. row ***************************
Table: t6
Non_unique: 1
Key_name: infoFTIdx
Seq_in_index: 1
Column_name: info
Collation: NULL
Cardinality: NULL
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: FULLTEXT
Comment:
Index_comment:
Visible: YES
1 row in set (0.09 sec)
//创建空间索引
mysql> CREATE TABLE t7 (g GEOMETRY NOT NULL )ENGINE=MyISAM;
Query OK, 0 rows affected (0.02 sec)
mysql> ALTER TABLE t7 ADD SPATIAL INDEX spatIdx(g);
Query OK, 0 rows affected, 1 warning (0.08 sec)
Records: 0 Duplicates: 0 Warnings: 1
mysql> SHOW INDEX FROM t7 \G
*************************** 1. row ***************************
Table: t7
Non_unique: 1
Key_name: spatIdx
Seq_in_index: 1
Column_name: g
Collation: A
Cardinality: NULL
Sub_part: 32
Packed: NULL
Null:
Index_type: SPATIAL
Comment:
Index_comment:
Visible: YES
1 row in set (0.07 sec)
- 使用CREATE INDEX创建索引
语法结构:CREATE [UNION | FULLTEXT | SPATIAL] INDEX index_name ON table_name (col_name [length],...) [ASC | DESC]
mysql> CREATE TABLE book_1
-> (
-> bookid INT NOT NULL,
-> bookname VARCHAR(255) NOT NULL,
-> authors VARCHAR(255) NOT NULL,
-> info VARCHAR(255) NULL,
-> comment VARCHAR(255) NULL,
-> year_publication YEAR NOT NULL
-> );
Query OK, 0 rows affected (0.17 sec)
//创建普通索引
mysql> CREATE INDEX BkNameIdx ON book_1(bookname);
Query OK, 0 rows affected (0.15 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> SHOW INDEX FROM book_1 \G
*************************** 1. row ***************************
Table: book_1
Non_unique: 1
Key_name: BkNameIdx
Seq_in_index: 1
Column_name: bookname
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
1 row in set (0.03 sec)
//创建唯一索引
mysql> CREATE UNIQUE INDEX BkcmtIdx ON book_1(bookId);
Query OK, 0 rows affected (0.28 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> SHOW INDEX FROM book_1 \G
*************************** 1. row ***************************
Table: book_1
Non_unique: 0
Key_name: BkcmtIdx
Seq_in_index: 1
Column_name: bookid
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
*************************** 2. row ***************************
Table: book_1
Non_unique: 1
Key_name: BkNameIdx
Seq_in_index: 1
Column_name: bookname
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
2 rows in set (0.04 sec)
//创建单列索引
mysql> CREATE INDEX BkcmIdx ON book_1(comment(50));
Query OK, 0 rows affected (0.10 sec)
Records: 0 Duplicates: 0 Warnings: 0
//创建组合索引
mysql> CREATE INDEX BkAuAndInfoIdx ON book_1(authors(20),info(50));
Query OK, 0 rows affected (0.15 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> SHOW INDEX FROM book_1 \G
*************************** 1. row ***************************
Table: book_1
Non_unique: 0
Key_name: BkcmtIdx
Seq_in_index: 1
Column_name: bookid
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
*************************** 2. row ***************************
Table: book_1
Non_unique: 1
Key_name: BkNameIdx
Seq_in_index: 1
Column_name: bookname
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
*************************** 3. row ***************************
Table: book_1
Non_unique: 1
Key_name: BkcmIdx
Seq_in_index: 1
Column_name: comment
Collation: A
Cardinality: 0
Sub_part: 50
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
*************************** 4. row ***************************
Table: book_1
Non_unique: 1
Key_name: BkAuAndInfoIdx
Seq_in_index: 1
Column_name: authors
Collation: A
Cardinality: 0
Sub_part: 20
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
*************************** 5. row ***************************
Table: book_1
Non_unique: 1
Key_name: BkAuAndInfoIdx
Seq_in_index: 2
Column_name: info
Collation: A
Cardinality: 0
Sub_part: 50
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
5 rows in set (0.04 sec)
mysql> CREATE TABLE t8
-> (
-> id INT NOT NULL,
-> info CHAR(255),
-> g GEOMETRY NOT null
-> )ENGINE=MyISAM;
Query OK, 0 rows affected (0.12 sec)
//创建全文索引
mysql> CREATE FULLTEXT INDEX infoFTIDx ON t8(info);
Query OK, 0 rows affected (0.07 sec)
Records: 0 Duplicates: 0 Warnings: 0
//创建空间索引
mysql> CREATE SPATIAL INDEX spatIdx ON t8 (g);
Query OK, 0 rows affected, 1 warning (0.17 sec)
Records: 0 Duplicates: 0 Warnings: 1
mysql> SHOW INDEX FROM t8 \g;
+-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible |
+-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+
| t8 | 1 | spatIdx | 1 | g | A | NULL | 32 | NULL | | SPATIAL | | | YES |
| t8 | 1 | infoFTIDx | 1 | info | NULL | NULL | NULL | NULL | YES | FULLTEXT | | | YES |
+-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+
2 rows in set (0.03 sec)
删除索引
MySQL中删除索引使用ALTER TABLE或者DROP INDEX语句,两者可实现相同的功能,DROP INDEX语句在内部被映射到一个ALTER TABLE语句中。
- 使用ALTER TABLE 删除索引
//语法格式:ALTER TABLE table_name DROP INDEX index_name;
mysql> SHOW CREATE TABLE book \G;
*************************** 1. row ***************************
Table: book
Create Table: CREATE TABLE `book` (
`bookid` int(11) NOT NULL,
`bookname` varchar(255) NOT NULL,
`authors` varchar(255) NOT NULL,
`info` varchar(255) DEFAULT NULL,
`comment` varchar(255) DEFAULT NULL,
`year_publication` year(4) NOT NULL,
UNIQUE KEY `UniquidIdx` (`bookid`),
KEY `year_publication` (`year_publication`),
KEY `BkNameIdx` (`bookname`(30)),
KEY `BkcmtIdx` (`comment`(50)),
KEY `BkAuAndInfoIdx` (`authors`(30),`info`(50))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
//删除索引
mysql> ALTER TABLE book DROP INDEX UniquidIdx;
Query OK, 0 rows affected (0.47 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> ALTER TABLE book DROP INDEX UniquidIdx;
Query OK, 0 rows affected (0.47 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> SHOW CREATE TABLE book \G
*************************** 1. row ***************************
Table: book
Create Table: CREATE TABLE `book` (
`bookid` int(11) NOT NULL,
`bookname` varchar(255) NOT NULL,
`authors` varchar(255) NOT NULL,
`info` varchar(255) DEFAULT NULL,
`comment` varchar(255) DEFAULT NULL,
`year_publication` year(4) NOT NULL,
KEY `year_publication` (`year_publication`),
KEY `BkNameIdx` (`bookname`(30)),
KEY `BkcmtIdx` (`comment`(50)),
KEY `BkAuAndInfoIdx` (`authors`(30),`info`(50))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
- 使用DROP INDEX语句删除索引
//语法结构:DROP INDEX index_name ON table_name;
mysql> SHOW CREATE TABLE book \G
*************************** 1. row ***************************
Table: book
Create Table: CREATE TABLE `book` (
`bookid` int(11) NOT NULL,
`bookname` varchar(255) NOT NULL,
`authors` varchar(255) NOT NULL,
`info` varchar(255) DEFAULT NULL,
`comment` varchar(255) DEFAULT NULL,
`year_publication` year(4) NOT NULL,
KEY `year_publication` (`year_publication`),
KEY `BkNameIdx` (`bookname`(30)),
KEY `BkcmtIdx` (`comment`(50)),
KEY `BkAuAndInfoIdx` (`authors`(30),`info`(50))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
//删除索引
mysql> DROP INDEX BkNameIdx ON book;
Query OK, 0 rows affected (0.15 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> SHOW CREATE TABLE book \G
*************************** 1. row ***************************
Table: book
Create Table: CREATE TABLE `book` (
`bookid` int(11) NOT NULL,
`bookname` varchar(255) NOT NULL,
`authors` varchar(255) NOT NULL,
`info` varchar(255) DEFAULT NULL,
`comment` varchar(255) DEFAULT NULL,
`year_publication` year(4) NOT NULL,
KEY `year_publication` (`year_publication`),
KEY `BkcmtIdx` (`comment`(50)),
KEY `BkAuAndInfoIdx` (`authors`(30),`info`(50))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
MySQL8.0新特性–支持降序索引
在MySQL中默认为升序排序,我们可以定义为降序排序
//定义方法
mysql> CREATE TABLE ts1
-> (
-> a INT,
-> b INT,
-> INDEX idx_a_b(a,b DESC)
-> );
Query OK, 0 rows affected (0.12 sec)
//查看细节
mysql> SHOW CREATE TABLE ts1 \G
*************************** 1. row ***************************
Table: ts1
Create Table: CREATE TABLE `ts1` (
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
KEY `idx_a_b` (`a`,`b` DESC)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
//为表ts1 添加80000条数据
mysql> DELIMITER ;;
mysql> CREATE PROCEDURE ts_insert ()
-> BEGIN
-> DECLARE i INT DEFAULT 1;
-> WHILE i < 80000
-> DO
-> insert into ts1 select rand()*80000, rand()*80000;
-> set i=i+i;
-> END WHILE;
-> commit;
-> END;;
Query OK, 0 rows affected (0.13 sec)
mysql> DELIMITER ;
mysql> CALL ts_insert();
//查看ts1数据表的执行计划
mysql> explain select * from ts1 order by a, b desc limit 5;
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| 1 | SIMPLE | ts1 | NULL | index | NULL | idx_a_b | 10 | NULL | 5 | 100.00 | Using index |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
//修改条件,再看看执行条件
mysql> explain select * from ts1 order by a desc, b desc limit 5;
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-----------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-----------------------------+
| 1 | SIMPLE | ts1 | NULL | index | NULL | idx_a_b | 10 | NULL | 17 | 100.00 | Using index; Using filesort |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-----------------------------+
1 row in set, 1 warning (0.00 sec)
15万+

被折叠的 条评论
为什么被折叠?



