当前位置: 首页 > article >正文

MySQL索引(三)

MySQL索引(三)

文章目录

  • MySQL索引(三)
    • 为什么建索引?
    • 怎么建立索引
      • 为什么不是说索引越多越好
      • 什么时候不用索引更好
    • 索引怎么优化
    • 索引失效
      • 如何解决索引失效

学习网站:https://xiaolincoding.com/

为什么建索引?

1.索引大大减少了MySQL需要扫描的数据量

如果没有建立索引,查数据的时间复杂度是O(n),查询效率低下;建立索引后,B+树是个多叉树,搜索的时间复杂度是O(logN),提高查询效率

2.索引帮助MySQL避免外部排序和使用临时表

3.将随机IO转变为顺序IO

索引是把数据顺序存放,这样可能相邻的数据会存储到一个连续的磁盘空间,这样就有可能是顺序IO了

怎么建立索引

适用于索引:

1.字段具有唯一性限制的,比如商品编码,id

2.经常使用==WHERE条件==的字段,如果是多个就创建联合索引

3.经常用于==GROUP BYORDER BY==的字段,这样在查询的时候就不用去做一次排序了,因为建立索引后在B+树中的记录是排序好的

不适应于索引的:

1.WHEREGROUP BYORDER BY中用不到的字段,不起到定位作用的字段不需要建立索引,因为索引也消耗物理空间

2.字段中大量重复数据,比如性别字段。因为MySQL中的查询优化器发现某个值在该字段占比很高,就会忽略索引,进行全表扫描

3.经常更新的字段不用创建索引,因为索引字段频繁更新,需要去维护B+树的有序性,频繁的重建索引会影响数据库性能

为什么不是说索引越多越好

  • 空间消耗:索引占用物理空间,数量越大,占据空间越大

多一个索引,就多一个B+树索引,表数据量越大,索引占用空间越大

  • 时间消耗:降低表的增删改查的效率,每次增删改查,B+树都需要维护索引有序性,进行动态维护

什么时候不用索引更好

建立索引就会有时间和空间上的消耗,见上文。

1.如果一个表经常被增删改的话,也就是读多写少场景下,不建立索引更好,因为维护索引的开销可能大于索引提升的性能

2.如果某个字段中的值高度重复,建立索引也没有用,查询优化器会选择全表扫描,这样建立的索引既占空间,也影响增删改的效率

索引怎么优化

  • 覆盖索引优化:

比如商品名和商品价格:select pro_id,pro_name,pro_price from table where pro_name="apple;",把商品名和商品价格建立一个联合索引,这使用使用上面的sql语句就利用覆盖索引优化了,因为索引中已经包含这两个字段的数据了,所以查询不会再次去查询主键索引,避免了回表,减少大量IO操作

  • 主键索引最好是自增的

如果是随机值,会造成页分裂,页分裂会导致大量内存碎片,使索引结构不紧凑,影响查询效率

  • 避免索引失效

1.使用左或左右模糊匹配会造成索引失效,like %xx like %xx%

2.当我们在查询条件中对索引列进行计算、函数、类型转换操作时都会造成索引失效

3.联合索引必须遵守最左匹配原则

4.WHERE字句中,如果OR前的条件列是索引列,OR后的条件列不是索引列,也会造成索引失效

  • 前缀查询优化

对于一些大字符串的索引,我们可以考虑使用前缀索引只对索引列的前缀部分建立索引,节省索引的存储空间

索引失效

如果用varchar定义一个日期字段,并且其中有个数据"20120101",如果这个time字段有索引,并且查询时的条件是where time=20120101不加单引号,会不会命中索引?

答案是不会。

因为MySQL在遇到字符串和数字比较时,会把字符串先转化为数字,然后进行比较。也就是对字符串执行一个CAST函数。

比如:

select* from table_name where time=20120101

实际上执行的是select* from table_name where CAST(time AS signed int)=20120101

索引字段进行了函数计算就会发生索引失效。

反过来,如果一个id字段是整型类型,查询的id=“1”,就不会发生索引失效

select* from table_name where id="1"

实际上执行的是select* from table_name where id=CAST("1 AS signed int")

索引字段并没有发生函数计算,所以不会索引失效

如何解决索引失效

MySQL8.0:函数索引和索引跳跃扫描机制

  • 函数索引

针对函数计算后的值建立一个索引,也就是该索引的值是函数计算后的值,这样就可以通过扫描索引来查询数据

比如:针对length(name)的计算结果建立一个索引

alter table t_user add key idx_name_length((length(name)))
explain select * from t_user where length(name)=6;

这时候就走索引了

image-20240828205738853

  • 索引跳跃扫描机制

之前使用联合索引时,如果不满足最左匹配原则会造成索引失效,8.0有了索引跳跃扫描机制之后,即使没有遵循最左匹配原则,任然可以使用联合索引

image-20240828210001059


http://www.kler.cn/a/282052.html

相关文章:

  • Vue3中实现插槽使用
  • 【计算机网络】水平触发与边缘触发有什么优缺点呢?
  • 使用nossl模式连接MySQL数据库详解
  • 【第五课】Rust所有权系统(一)
  • Unity 2022 Nav Mesh 自动寻路入门
  • 21.3D surface
  • 图像搜索引擎DIY【CLIP+FAISS】
  • 力扣231题详解:2的幂的多种解法与模拟面试问答
  • DrawDB数据库设计工具本地部署结合内网穿透实现团队异地协作办公
  • Ubuntu22.04安装深度学习的GPU环境详细教程(小白图文,显卡驱动、CUDA、cuDNN、PyTorch一步到位)
  • Scrapy 项目部署Scrapyd
  • WHAT - 通过 react-use 源码学习 React(State 篇)
  • html+css+js网页设计 婚庆类型模版 12个页面
  • 关于复杂业务逻辑使用SQL还是java代码实现的思考
  • Golang安装与环境配置
  • 严重腰椎滑脱、无法走路,江山邦尔骨科医院机器人辅助手术为患者完美复位
  • XML 数据格式介绍及其应用
  • 1.5.1、输入输出技术
  • 【编程知识】c++中的结构体和JavaScript中的对象有啥异同
  • 树上dp+分组背包类问题
  • SpringIoc体系结构设计
  • 算法的学习笔记—连续子数组的最大和
  • 【hot100篇-python刷题记录】【杨辉三角】
  • 【Linux】进程概念
  • Andon安灯系统在汽车零部件工厂起到什么作用?
  • 小程序常用界面交互api