[MySQL索引]1.MySQL索引的基本使用

索引作用

作用:当表中的数据达到几十万甚至几百万的时候,SQL查询所花费的时间很长,导致业务超时出错,此时需要索引来加速SQL查询

索引也是需要存储成索引文件的,因此对索引的操作涉及磁盘I/O,如果索引创建过多,使用不当,也会造成SQL查询时进行大量无用的磁盘I/O操作,降低SQL的查询效率,因此掌握良好的索引创建原则是非常重要的。

索引分类

索引本质也是一种数据结构,是创建在表上的,是对数据库表中的一列或者多列的值进行排序的一种结果。索引的核心是提高查询的速度

  • 物理:

    • 聚集索引
    • 非聚集索引
  • 逻辑:

    • 普通索引:没有任何限制,可以给任何类型的字段创建普通索引(创建新表&已创建的表,数量是不限的,但是不建议创建过多索引,一张表的一次SQL查询只能用一个索引

    • 唯一性索引:自动创建,使用UNIQUE修饰的字段,值不能重复,主键索引就隶属于唯一性索引

    • 主键索引:使用PRIMARY KEY修饰的字段会自动创建索引

      • 如果没有加主键,MyISAM不会自动为表添加一列主键,因为MyISAM中数据和索引是分开存放的,有没有索引数据都可以正常存储;
      • 如果没有加主键,InnoDB会默认创建一个整型字段作为主键,因为InnoDB中数据和索 引是存储在一个文件中(xxx.ibd)的,必须创建索引树,然后在索引树下存数据,没有索引树就无法存储数据
    • 单列索引:在一个字段上创建索引

    • 多列索引:在表的多个字段上创建索引(uid+cid,多列索引必须使用到第一个列,才能用到多列索引,否则索引用不上,比如利用uid作过滤条件可以用到多列索引,只用到cid作过滤条件则用不到多列索引

    • 全文索引(MyISAM支持):使用FULLTEXT参数可以设置全文索引,只支持CHAR、VARCHAR和TEXT类型的字段上,常用于数据量较大的字符串类型,可以提高查询速度

      文本的搜索很少直接在数据库中搜索,所以实际上线上项目需要支持专门的搜索功能,给后台服务器添加专门的搜索引擎支持快速高效的搜索, 比如elasticsearch 简称es

      C++开源搜索引擎---->workflow


索引的创建和删除

  • 创建表的时候指定索引字段
CREATE TABLE index1
(
    name VARCHAR(20),
    sex ENUM(‘m’,'w'),
    INDEX(id, name)	// 对指定字段上的数据进行排序,先按照id,如果相同,则按照name
);
  • 在已经创建好的表上添加索引
CREATE [UNIQUE] 索引名 ON 表名 (属性名(length) [ASC|DESC])
// 在字符串类型的字段上创建建索引时,一般会通过length指定利用一定长度的字符串来建立索引,往往不需要使用完整的字符串,这也是一种优化策略

CREATE index name_age_idx on student(name,age); // 创建多列索引

CREATE index nameindex on student(name);  // 在student表上的name字段添加索引

在这里插入图片描述

可以看到我们成功在student数据库表上添加了索引nameindex

  • 删除索引
DROP INDEX 索引名 ON 表名
  • 查看表的索引字段信息(包括使用的索引类型B+树索引,哈希索引
show indexes from 表名;

在这里插入图片描述


注意:我们在数据库表的字段上添加索引,索引并不一定能够用上,MySQL Server会进行一个优化,如果通过索引找到的数据量比较接近直接扫描表得到的数据量,那就不使用索引,因为读取索引文件需要进行磁盘I/O,然后还要扫描索引树,如果数据取不完,还是要到数据库表上进行搜索

还有一点要注意:

作为过滤条件的字段,如果在过滤条件中涉及到了类型强转,那么就不会使用在该字段上添加的索引

CREATE INDEX pwdindex on t_user(password); // 先在t_user表的password字段上添加索引

select * from t_user where password=1000000; // 然后使用该索引字段作为过滤条件进行查询

在这里插入图片描述

我们会发现这个查询的时间好像有一点久…,使用explain查看以下语句的执行过程:
在这里插入图片描述

我们发现虽然我们在password字段上添加了索引,但是查询的时候并没有使用,这是为什么呢?(原因在于我们查询的时候,过滤条件中给字符串类型的password传的是整型的1000000,所以涉及到数据类型的强制转换,而如果在过滤条件中某字段涉及到了类型强转,那么就不会使用在该字段上添加的索引)

select * from t_user where password='1000000';// 我们避免类型强转,再执行一次查询

在这里插入图片描述


关于索引优化:

  • 经常作为where条件过滤的字段考虑添加索引

  • 为字符串列创建索引字段时,尽量规定索引的长度,而不能让索引值的长度key_len过长

  • 索引字段涉及类型强转、mysql函数调用、表达式计算等,索引就用不上了


索引的执行过程

使用explain查看SQL语句的执行计划,也可以帮助我们去分析索引的执行

explain结果字段分析

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

下酒番陪绅士

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

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

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

打赏作者

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

抵扣说明:

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

余额充值