MySQL--数据库索引

前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除

MySQL数据库--索引

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

一、索引简介

1、索引的含义和特定

索引是一个单独的、存储在磁盘上的数据库结构,包含着对数据表里所有记录的引用指针。使用索引可以快速找出在某个或多个列中有一特定值的行,所有MySQL列类型都可以被索引,对相关列使用索引是提高查询操作速度的最佳途径。

索引的优点主要有以下:

  • 通过创建唯一索引,可以证数据库表中每一行数据的唯一性
  • 可以大大加快数据的查询速度这也是创建索引的主要原因
  • 在实现数据的参考完整性方面,可以加速表和表之间的连接
  • 在使用分组和排序子句进行数据查询时,也可以显著减少查询中分组和排序的时间。

增加索引也有不利的方面:

  • 创建索引和维护索引要耗费时间,并且随着数据量的增加所耗费的时间也会增加
  • 索引需要占磁盘空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果有大量的索引,索引文件可能比数据文件更快达到最大文件尺寸。
  • 当对表中的数据进行增加、删除和修改的时候,索引也要动态地维护,这样就降低了数据的维护速度。

2、索引的分类

2.1、普通索引和唯一索引

普通索引是MySQL中的基本索引类型,允许在定义索引的列中插入重复值和空值

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

2.2、单列索引和组合索引

单列索引即一个索引只包含单个列一个表可以有多个单列索引 组合索引是指在表的多个字段组合上创建的索引,只有在查询条件中使用了这些字段的左边字段时,索引才会被使用。使用组合索引时遵循最左前缀集合

2.3、全文索引

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

2.4、空间索引

空间索引是对空间数据类型的字段建立的索引,MySQL中的空间数据类型有4种,分别是GEOMETRYPOINTLINESTRINGPOLYGON。MySQL使用SPATIAL关键字进行扩展,使得能够用创建正规索引类似的语法创建空间索引。创建空间索引的列,必须将其声明为NOTNULL,空间索引只能在存储引擎为MyISAM的表中创建。

3、索引的设计原则

设计数据库索引时应遵循以下原则以确保性能优化:

  • 索引数量应适中,过多索引会占用空间并降低数据更新操作的性能
  • 对于频繁更新的表,应避免创建过多索引,且索引列应尽量精简,仅对常用于查询的字段建立索引
  • 对于数据量小的表,索引可能不会带来性能提升。应针对条件表达式中常用且具有不同值较多的列建立索引,避免在值少的列上创建索引
  • 对于具有唯一性特征的数据,使用唯一索引以确保数据完整性并提高查询速度
  • 对于经常需要排序或分组的列,建立索引或组合索引以优化性能。

二、创建索引

1、创建表时创建索引

其基本语法格式如下:

 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为索引值;length为可选值,表示索引的长度,ASC或DESC表示升序或降序

(1)创建普通索引

 # 在book表中的year_publication字段上建立普通索引
 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)
 );
 # 使用show create table查看表结构
 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`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1
 1 row in set (0.00 sec)
 # 发现year_publication字段成功建立了索引,使用explain语句查看所有是否正在使用
 mysql> explain select * from book where year_publication=1990 \G
 *************************** 1. row ***************************
            id: 1
   select_type: SIMPLE   # SELECT查询类型
         table: book     # 数据表名字
    partitions: NULL 
          type: ref      # 本数据表与其他表之间的关联关系
 possible_keys: year_publication     # 可选用的各个索引
           key: year_publication     # 实际选用的索引
       key_len: 1        # 索引按字节计算的长度
           ref: const    # 关联关系中另一个数据表里的数据列名
          rows: 1        # 预计从数据表读出的数据行的个数
      filtered: 100.00   
         Extra: Using index condition    # 与关联操作有关的信息
 1 row in set, 1 warning (0.00 sec)

(2)创建唯一索引

创建唯一索引的主要原因是减少查询索引列操作的执行时间,尤其是对比较庞大的数据表。它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一

 # 创建一个表t1,在表的id字段上使用unique关键字创建唯一索引
 create table t1(
 id     int not null,
 name   char(30) not null,
 unique  index uniqIdx(id)
 );
 # 发现id字段上成功建立了一个名为UniqIdx的唯一索引
 show create table t1 \G
 *************************** 1. row ***************************
        Table: t1
 Create Table: CREATE TABLE `t1` (
   `id` int(11) NOT NULL,
   `name` char(30) NOT NULL,
   UNIQUE KEY `uniqIdx` (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1
 1 row in set (0.00 sec)

(3)创建单列索引

单列索引是在数据表中的某一个字段上创建的索引一个表中可以创建多个单列索引。前面两个例子中创建的索引都为单列索引。

 # 创建一个表t2,在表的name字段上创建单列索引
 create table t2(
 id    int not null,
 name  char(50) null,
 index  SingleIdx(name(20))
 );
 # 可以看到,id字段上成功建立一个名为Single的单列索引,长度为20
 mysql> show create table t2 \G
 *************************** 1. row ***************************
        Table: t2
 Create Table: CREATE TABLE `t2` (
   `id` int(11) NOT NULL,
   `name` char(50) DEFAULT NULL,
   KEY `SingleIdx` (`name`(20))
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1
 1 row in set (0.00 sec)

(4)创建组合索引

组合索引是在多个字段上创建一个索引

 # 创建表t3,在表中的id、name和age字段上建立组合索引
 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)
 );
 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=latin1

(5)创建全文索引

FULLTEXT全文索引可以用于全文搜索。只有MyISAM存储引擎支持FULLTEXT索引,并且只为CHAR、VARCHAR和TEXT列创建索引。索引总是对整个列进行,不支持局部(前缀)索引。

 # 创建表4,在表中的info字段建立全文索引
 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;

(6)创建空间索引

空间索引必须在 MyISAM 类型的表中创建,且空间类型的字段必须为非空

 # 创建表t5,在空间类型为GEOMETRY的字段上创建空间索引
 create table t5(
 g   geometry not null,
 SPATIAL  index spatIdx(g)
 )engine=MyISAM;

2、在已经存在的表删创建索引

在已经存在的表中创建索引,可以使用ALTER TABLE或者CREATE INDEX语句,

(1)使用alter table语句创建索引

其基本语法如下:

 alter table table_name add [unique|fulltext|spatial] [index|key]
 [index_name] (col_name[length],...) [ASC|DESC]
# 向book表中的bookname字段上建立名为BkNameIdx的普通索引
# 添加索引之前,使用show index语句查看指定表中创建的索引
mysql> show index from book \G
*************************** 1. row ***************************
        Table: book			# 创建索引的表
   Non_unique: 1			# 1代表非唯一索引,0代表唯一索引
     Key_name: year_publication	# 索引名称
 Seq_in_index: 1				# 该字段在索引中的位置,单列索引该值为1
  Column_name: year_publication	# 定义索引的列字段
    Collation: A	
  Cardinality: 0
     Sub_part: NULL			# 索引的长度
       Packed: NULL	
         Null: 				# 表示该字段能否为空值
   Index_type: BTREE		# 索引类型
      Comment: 
Index_comment: 
1 row in set (0.00 sec)
------# 添加索引
alter table book add index BkNameIdx( bookname(30));

# 在book表的bookId字段上建立名称为UniqidIdx的唯一索引
alter table book add unique index UniqidIdx(bookId);

# 在book表的comment字段上建立单列索引
alter table book add index BkcmtIdx(comment(50));

# 在book表的authors和info字段上建立组合索引
alter table book add index BkAuAndInfoIdx(authors(30),info(50));

# 创建表t6,在表上使用alter table创建全文索引
create table t6(
id       int not null,
info     char(255)
)engine=MyISAM;		# MySQL默认引擎InnoDB不支持全文索引
alter table t6 add fulltext index infoFTIdx(info);

# 创建表t7,在表的空间数据类型字段g上创建名称为spatIdx的空间索引
create table t7(g GEOMETRY NOT NULL)engine=MyISAM;
alter table t7 add spatial index spatIdx(g);

(2)使用create index创建索引

CREATE INDEX语句可以在已经存在的表上添加索引。在MySQL中,CREATE INDEX被映射到一个ALTER TABLE 语句上,基本语法结构为:

create [unique|fulltext|spatial] index index_name
on table_name (col_name[length],...) [ASC|DESC]
# 把原book删除,再次创建一个无索引值的book表
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
);
# 在book表中的bookname字段建立名为BkNameIdx的普通索引
create index BkNameIdx ON book(bookname);

# 在book表的bookId字段上建立名称为UniqidIdx的唯一索引
create unique index UniqidIdx ON book(bookId); 

# 在book表的comment字段上建立单列索引
create index BkcmtIdx on book(comment(50));

# 在book表的authors和info字段上建立组合索引
create index BkAuAndInfoIdx on book(authoris(20),info(50));

# 在t6表上使用alter table创建infoFTIdx全文索引
create fulltext index infoFTIdx on t6(info);

# 重新创建表t7,在表的空间数据类型字段g上创建名称为spatIdx的空间索引
create spatial index spatIdx on t7(g);

三、删除索引

MYSOL中删除索引使用ALTER TABLE或者DROP INDEX语句,两者可实现相同的功能DROPINDEX语句在内部被映射到一个ALTER TABLE 语句中。

1、使用alter table删除索引

其基本语法如下:

alter table table_name drop index index_name
# 删除book表中名称为UniqidIdx的唯一索引
alter table book drop index UniqidIdx;

2、使用drop index语句删除索引

其基本语法格式如下:

​drop index index_name on table_name;
# 删除book表中名称为BkAuAndInfoIdx的组合索引
drop index BkAuAndInfoIdx on book;

致谢

在此,我要对所有为知识共享做出贡献的个人和机构表示最深切的感谢。同时也感谢每一位花时间阅读这篇文章的读者,如果文章中有任何错误,欢迎留言指正。 

学习永无止境,让我们共同进步!!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小李学不完

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值