千家信息网

Mysql之索引介绍

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,定义:索引用于快速找出某个列中有一特定值的行。不使用索引,MySql必须从第一条记录开始读完整个表,直到找出相关的行。表越大,查询数据所花费的时间越多。如果表中查询的列有一个索引,Mysql能快速到达
千家信息网最后更新 2026年11月01日Mysql之索引介绍

定义:

索引用于快速找出某个列中有一特定值的行。

不使用索引,MySql必须从第一条记录开始读完整个表,直到找出相关的行。表越大,查询数据所花费的时间越多。

如果表中查询的列有一个索引,Mysql能快速到达一个位置去搜索数据文件,而不必查看所有数据。


简介:

索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可以提高数据库中特定数据的查询速度。

索引是一个单独的、存储在磁盘上的数据库结构,他们包含着对数据表里所有记录的引用指针。

使用索引用于快速找出某个或者多个列中有一特定值的行,所有Mysql列类型都可以被索引,对相关列使用索引是提高查询操作速度的最佳途径。

例如:数据库中有2万条记录,现在要执行这样一个查询:

select * from table where num=10000

如果没有索引,必须遍历整个表,直到num等于10000的这一行被找到为止。

如果在num列上创建索引,MySql不需要任何扫描,直接在索引里面找到10000,就可以得知这一行的位置。

索引是存储引擎实现的,因此,每种存储引擎的索引都不一定完全相同,并且每种存储引擎也不一定支持所有索引类型。

根据存储引擎定义每个表的最大索引数和最大索引长度。所有存储引擎支持每个表至少16个索引,总索引长度至少为256字节。大多数存储引擎有更高的限制。

MySql中索引的存储类型有两种:BTREE和HASH,具体和表的存储引擎相关;MyISAM和InnoDB存储引擎都支持BTREE索引;MEMORY/HEAP存储引擎可以支持BTREE和HASH索引。


索引优点:

1、通过创建唯一索引,可以保证数据库表中每一行数据的唯一性。

2、可以大大加快数据的查询速度,这也是创建索引的最主要的原因。

3、在实现数据的参考完整性方面,可以加速表和表之间的链接。

4、在使用分组和排序子句进行数据查询时,也可以显著减少查询中分组和排序的时间。


索引的缺点:

1、创建索引和维护索引要耗费时间,并且随着数据量的增加所耗费的时间也会增加。

2、索引需要占据磁盘空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果有大量的索引,索引文件可能比数据文件更快达到最大文件尺寸。

3、当对表中的数据进行增加、删除和修改的时候,索引也要动态维护,这样就降低了数据的维护速度。


MySql索引的分类:

1、普通索引和唯一索引

普通索引:Mysql中最基础的索引类型,允许在定义索引的列中插入重复值和空值。

唯一索引:索引列的值必须唯一,但允许有空值。

如果是组合索引,则列值和组合必须唯一。主键索引是一种特殊唯一索引,不行允许有空值。

2、单列索引和组合索引

单列索引:一个索引只包含一个列,一个表也可以有多个单列索引。

组合索引:在表的多个字段组合上创建的索引,只有在查询条件中使用了这些字段的左边字段时,索引才会被使用。使用组合索引时遵循最左前缀集合。

3、全文索引

全文索引类型为FULLTEXT,在定义索引的列上支持值得全文查找,允许在这些索引列中插入重复值和空值。全文索引可以在CHAR,VARCHAR或者TEXT类型上创建。

只有MyISAM存储引擎支持全文索引。

4、空间索引

空间索引是对空间数据类型的字段建立索引,Mysql中的空间数据有4中:GEOMETRY、POINT、LINESTRING和POLYGON。Mysl使用SPATIAL关键字进行扩展,使得能够创建正规索引类似的语法创建空间索引。

创建空间索引的列,必须将其声明为NOT NULL,空间索引只能在存储引擎为MyISAM中创建。


索引表的设计原则:

1、索引表不是越多越好,一个表中如果有大量索引,不仅占用硬盘空间,还影响增删改查等语句的性能,因为当表中的数据更改的同时,索引也会进行调整和更新。

2、避免经常更新的表进行过多的索引,并且索引表中的列尽可能少。而经常查询的字段应该创建索引,但要避免添加不必要的字段。

3、数据量小的表最好不要使用索引。遍历的时间短与索引的时候,并不会产生优化效果。

4、在条件表达式中经常用到的不同值较多的列上建立索引,在不同值少的列上不要建立索引。比如性别。

5、当唯一性是某种数据本身的特征时,指定唯一索引。使用唯一索引需要能确保定义的列的数据的完整性,以提高数据的查询速度。

6、在频繁进行排序或者分组(即进行group by 或order by操作)的列上建立索引,如果待排序的列有多个,可以在这些列上建立组合索引。

创建语法:

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]UNIQUE:唯一索引FULLTEXT:全文索引SPATIAL:空间索引[INDEX|KEY]:作用相同,创建索引col_name:需要创建索引的字段列,必须在表中定义的列index_name:指定索引名,如果不指定Mysql默认col_name为索引值。length:索引长度,仅字符串型才可指定[ASC|DESC]:升序、降序

1、创建普通索引:

mysql> create database lxqdb;mysql> use lxqdb;mysql> create table book      -> (    -> book_id int not null,    -> book_name 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)    -> );

查看:

mysql> show create table book \GKEY `year_publication` (`year_publication`)     # 成功建立索引,mysql自动添加索引名:year_publication


查看索引是否被正确使用:

mysql> explain select * from book where year_publication=2018\G*************************** 1. row ***************************              id: 1          select_type: SIMPLE        # 表示简单的select,不可以使用子查询。其他取值:PRIMARY | UNION | SUBQUERY             table: book         # 行指定数据表名,它们被按照读取的先后顺序排列             type: ref          # 行指定本数据表和其他数据表之间的关联。其他取值:system | const | eq_ref | ref | range | index | ALL         possible_keys: year_publication         # 可以选用的索引              key: year_publication         # 实际选用的索引            key_len: 1                   # 索引按字节计算长度,值越小表示越快              ref: const         # 关联另一个数据表里的列名             rows: 1           # 执行查询时预计会从这个数据表里读出的数据行的个数             Extra: Using index condition      # 关联操作信息    1 row in set (0.00 sec)


2、创建唯一索引:

在比较大庞大的数据表中,为了减少索引列操作的时间。与普通索引唯一不同的是:索引列的值必须唯一,但允许有空值。如果是组合索引,则 列值的组合必须唯一。

创建tb1表,id字段使用UNIQUE创建唯一索引。

mysql> create table tb1    -> (    -> id int not null,    -> name char(20) not null,    -> UNIQUE INDEX uidx(id)    -> );

查看:

mysql> show create table tb1\GUNIQUE KEY `uidx` (`id`)           # id字段上创建了名为uidx的唯一索引。


3、创建单列索引:

单列索引是再数据表中某一字段上创建的索引,一个表中可以创建多个单列索引。

上面的两个例子中创建的索引都是单列索引。

创建tb2表,在表中name字段上创建单列索引。

mysql> create table tb2    -> (    -> id int not null,    -> name char(20) not null,    -> INDEX Single_idx(name(10))    -> );

查看:

mysql> show create table tb2\GKEY `Single_idx` (`name`(10))            # name字段上创建名为Single_idx且长度10的单列索引。

4、创建组合索引:

在多个字段上创建索引。

创建tb3表,id,name,age为索引

mysql> create table tb3    -> (    -> id int not null,    -> name char(20) not null,    -> age int not null,    -> info varchar(255),    -> INDEX Multi_idx(id,name,age)    -> );

查看:

mysql> show create table tb3\GKEY `Multi_idx` (`id`,`name`,`age`)            # 建立了组合索引注意:组合索引可起几个索引的作用,但是使用时并不是随便查询哪个字段都可以使用索引,而是遵从"最左前缀"最左前缀:利用索引中最左边的列集来匹配,索引中按id\name\age的顺序存放,索引可以搜索下面的字段组合:(id,name,age)、(id,name)、id。如果列不构成索引最左前缀,mysql不能使用局部索引,如age或者name,age组合则不能使用索引。查询id和name字段的索引情况:mysql> explain select * from tb3 where id=1 and name='lxq'\Gkey: Multi_idx            # 可以看到使用了MultiIdx的索引。查询name和age字段的索引情况:mysql> explain select * from tb3 where name='lxq' and age=23\Gkey: NULL                 # 表示并没有使用索引查询。

5、创建全文索引:

只有myisam引擎支持且只为char,varchar,text列。索引总是对整列进行,不支持局部索引。

创建表tb4,在info字段上建全文索引:

mysql> create table tb4    -> (    -> id int not null,    -> name char(20) not null,    -> age int not null,    -> info  varchar(255),    -> FULLTEXT INDEX Fulltext_idx(info)    -> )engine=myisam;

查看:

mysql> show create table tb4\GFULLTEXT KEY `Fulltext_idx` (`info`)            # 名为Fulltext_idx的FULLTEXT。适合大型数据,不要在小数据内使用。


6、创建空间索引:

只有myisam引擎支持且只为not null列。

创建tb5表,GEOMETRY字段上创建空间索引:

mysql> create table tb5    -> (    -> gmt geometry not null,    -> SPATIAL INDEX Spat_idx(gmt)    -> )engine=myisam;

查看:

mysql> show create table t5\G;

SPATIAL KEY `Spat_idx` (`gmt`) # 名为Spat_idx的GEOMETRY

---------------------------------------------------------------------------------------

我是分割线1

---------------------------------------------------------------------------------------

已存在表中创建索引:

1、在book表中的bookname字段上建bookname_idx的普通索引:

mysql> alter table book add index bookname_idx(book_name(30));

查看:

mysql> show index from book\G*************************** 2. row ***************************          Table: book       Non_unique: 1          # 索引非唯一,1代表非唯一索引,0代表唯        Key_name: bookname_idx     # 索引名      Seq_in_index: 1          # 索引中的位置,1为单列,组合索引为每个字段在索引定义中的顺序       Column_name: book_name      # 索引的列字段        Collation: A        Cardinality: 0         Sub_part: 30         # 索引长度         Packed: NULL          Null:            # 字段是否为空       Index_type: BTREE        # 索引类型         Comment:      Index_comment:          Table: book


2、在bookid字段上建立名为UniqidIdx的唯一索引:

mysql> alter table book add UNIQUE INDEX Uniqid_idx(book_id);

查看:

mysql> show index from book \G;*************************** 1. row ***************************          Table: book        Non_unique: 0                    # 索引唯一,1代表非唯一索引,0代表唯一索           Key_name: Uniqid_idx       Seq_in_index: 1


3、在comment上创建单列索引:

mysql> alter table book add INDEX coment_idx(comment(50));

查看:

mysql> show index from book \GSub_part: 50        #只要检索前50个字符

4、在book的authors和info上建组合索引:

mysql> alter table book add INDEX Au_Info_idx(authors(20),info(50));

查看:

mysql> show index from book \G;     Key_name: Au_Info_idx Seq_in_index: 1       # 索引序列1   Column_name: authors*******************************    Key_name: Au_Info_idx Seq_in_index: 2             # 索引序列2  Column_name: info


5、在tb6表gmt字段建空间索引:

建表:

mysql> create table tb6 ( gmt geometry not null)engine=myisam;

增加空间索引:

mysql> alter table tb6 add SPATIAL INDEX spat_idx(gmt);

查看:

mysql>show index from tb6\G

---------------------------------------------------------------------------------------

我是分割线2

---------------------------------------------------------------------------------------

查看索引:

mysql> show create table book \G  UNIQUE KEY `Uniqid_idx` (`book_id`),  KEY `year_publication` (`year_publication`),  KEY `bookname_idx` (`book_name`(30)),  KEY `coment_idx` (`comment`(50)),  KEY `Au_Info_idx` (`authors`(20),`info`(50))或mysql>show index from book\G


删除索引:

mysql> alter table book drop index Uniqid_idx; # 删除索引名为Uniqid_idx的索引。

注意:

添加AUTO_INCREMENT约束字段的唯一索引不能被删除。


或


mysql> drop index coment_idx on book; # 删除book表内索引名为coment_idx的索引。

---------------------------------------------------------------------------------------

我是分割线3

---------------------------------------------------------------------------------------

总结:

1、索引对数据库的如此重要,应该如何使用?

为数据库选择正确的索引是一项复杂的任务。

如果索引列较少,则需要的磁盘空间和维护开销都较少。

如果在一个大表上创建了多种组合索引,索引文件也膨胀的很快。

另一面索引较多可覆盖更多的查询。

删除创建索引不影响应用程序,也不影响数据库架构,因此应尝试多个不同的索引,从而建立最优的索引。


2、尽量使用短索引。

对字符串类型的字段进行索引,如果可能应该指定一个前缀长度。

例如:有一个char(255)的列,如果在前10个或30个字符内,多数值是唯一的,则不需要对整个列进行索引。

短索引不仅可以提高查询速度而且可以节省磁盘空间、减少I/O操作。


3、是不是索引建立得越多越好?

合理的索引可以提高查询速度,但是不是索引越多越好。在执行插入语句的时候,mysql要为新插入的记录建立索引,所以过多的索引会导致插入操作变的非常慢。

原则上是只在查询用的字段才建立索引。


4、为甚查询语句中的索引没有起作用?

在一些情况下,查询语句中使用了带有索引字段。但索引字段没有起作用。

例如:在where 条件的like关键字匹配的字符串以"%"开头,这种情况下不会起作用。

where条件中使用or关键字链接条件,如果有1个字段没有使用索引,那么其他的索引也不会起作用。

如果使用多列索引,但是没有使用多列索引中的第一个字段,那么多列索引也不会起作用。


索引 数据 字段 查询 空间 组合 引擎 存储 数据表 类型 支持 全文 数据库 作用 速度 长度 多个 时间 普通 前缀 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网最新的科技有限公司 猪兼强互联网科技 远拓互联网科技 互联网科技英文翻译 互联网科技股午盘股票涨跌 互联网科技创新企业排名 互联网汽车科技小镇 北京三清互联网科技 宁波青枫互联网科技有限公司 团飞科技与伯堂互联网服务平台 互联网时代科技改变生活 深圳育鹏互联网科技有限公司招聘 本届互联网博览会上的黑科技 996高科技互联网公司 企晟互联网信息科技有限公司 山东子淼互联网科技有限公司 黑科技 体验场景 互联网大会 四川互联网展示科技馆设计 中国新注册互联网科技 北京天晋互联网科技有限公司 手冲咖啡和咖啡机区别 互联网科技公司华为 互联网科技集团 互联网 科技馆 开启互联网科技时代小说 电子商务与互联网科技的关系 广州富喜互联网络科技 互联网科技包装股份有限公司上市 众联互联网络科技 网互联网络科技
0