MySQL - 索引原理及其优化(一)

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: MySQL - 索引原理及其优化(一)


image.pngimage.png

[10,15,18,20,21] 
 |  |  |  |  | 
[x1,x4,x2,x3,x5]

下面的x是模拟数据再磁盘上的存储位置.这个时候如果我们需要查找15岁的人的名字.我们可以对盖数组进行二分查找.众所周知,二分查找的时间复杂度为O(logn).查找到之后再根据具体的位置去获取真正的数据.

PS:MySQL中的索引不是使用的数组,而是使用的B+树(后面讲),这里用数组举例只是因为比较好理解。

 

索引能为我们带来什么?

如上面所说,索引能帮助我们快速的查找到数据.其次因为索引中的值是顺序储存,那么可以帮助我们进行orderby操作.而且索引中也是存储了真正的值的,因此有一些的查询直接可以在索引中完成(也就是覆盖索引的概念,后面会提到).

总结一下索引的优点就是(《高性能》书中总结的):

  • 减少查询需要扫描的数据量(加快了查询速度)
  • 减少服务器的排序操作和创建临时表的操作(加快了groupby和orderby等操作)
  • 将服务器的随机IO变为顺序IO(加快查询速度).

索引有哪些缺点呢?

首先索引也是数据,也需要存储,因此会带来额外的存储空间占用.其次,在插入,更新和删除操作的同时,需要维护索引,因此会带来额外的时间开销.

总结一下:

  • 索引占用磁盘或者内存空间
  • 减慢了插入更新操作的速度

实际上,在一定数据范围内(索引没有超级多的情况下),建立索引带来的开销是远远小于它带来的好处的,但是我们仍然要防止索引的滥用.

都有哪些类型的索引?

对于MySQL来说,在服务器层并不实现索引,而是交给存储引擎来实现的,因此不同的存储引擎实现的索引类型不太一样.InnoDB作为当前使用最为广泛的存储引擎,使用的是B+树索引,因此我们大部分时间提到的索引也都是指的它.

MySQL主要有以下几种索引:

  • B-树索引/B+树索引
  • 哈希索引
  • 空间数据索引
  • 全文索引

本文只学习B-树索引和B+树索引.

B-树索引和B+树索引

这里不会特别详细的解释B-树和B+树的数据结构原理,有兴趣的小伙伴可以移步参考文章中的文章.或者通过google自行了解.

B-树

B-树是一棵多路平衡查找树,对于一棵M阶的B-树有以下的性质:

  1. 根节点至少有两个子女.
  2. 每个节点包含k-1个元素和k个孩子,其中m/2 <= k <= m.
  3. 每一个叶子节点都包含k-1个元素,其中m/2 <= k <= m.
  4. 所有的叶子节点位于同一层.
  5. 每个节点中的元素从小到大排列,那么k-1个元素正好是k个孩子包含的值域的划分.

这么说可能会有一些难理解,可以将B-树理解为一棵更加矮胖的二叉搜索树.

B+树

B+树是B-树的进阶版本,在B-树的基础上又做了如下的限制:

  1. 每个中间节点不保存数据,只用来索引,也就意味着所有非叶子节点的值都被保存了一份在叶子节点中.
  2. 叶子节点之间根据自身的顺序进行了链接.

这样可以带来什么好处呢?

  1. 中间节点不保存数据,那么就可以保存更多的索引,减少数据库磁盘IO的次数.
  2. 因为中间节点不保存数据,所以每一次的查找都会命中到叶子节点,而叶子节点是处在同一层的,因此查询的性能更加的稳定.
  3. 所有的叶子节点按顺序链接成了链表,因此可以方便的话进行范围查询.

怎样创建高性能的索引?

由于优化索引和优化查询一般是分不开的,因此这一块可能会包含部分的查询优化内容.

前缀索引和索引选择性

如果希望给一个很长的字符串上添加索引,那么可以考虑使用前缀索引.在正式介绍前缀索引之前,我们先大概考虑一下索引的工作步骤,数据库使用索引进行查找的时候,一般是如下几步:

  1. 在索引的B+树上找到对应的值,比如找到学校名称为卡塞尔学院的一条记录,并且拿到这条数据在磁盘上的地址.
  2. 根据地址去磁盘上查找,拿到该条数据所有的值.

那么假如在所有的学校名称的值中,卡塞尔就可以唯一的标识这条数据,那么用卡塞尔来做索引是否可以达到和卡塞尔学院做索引相同的效果?

答案是肯定的,而使用卡塞尔的话,是可以减少索引的大小到原来的60%的.这就是前缀索引的作用.

前缀索引: 在对一个比较长的字符串进行索引时,可以仅索引开始的一部分字符,这样可以大大的节约索引空间,从而提高索引效率.但是这样也会降低索引的选择性.

索引的选择性: 不重复的值/所有的值. 可以看出索引的选择性为0-1,最高的就是该列唯一,没有重复值.所以唯一索引的效率是比较好的.

但是在一般情况下,较长的字符串的一些前缀的选择性也是比较好的,这个我们可以算出来.使用下面的语句:

select 
    count(distinct left(school_name,3))/count(*) as sch3, 
    count(distinct left(school_name,4))/count(*) as sch4,
    count(distinct left(school_name,5))/count(*) as sch5,
    count(distinct school_name)/count(*) as original
from 
    user;
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
15天前
|
关系型数据库 MySQL 索引
mysql 分析5语句的优化--索引添加删除
mysql 分析5语句的优化--索引添加删除
12 0
|
21天前
|
存储 关系型数据库 MySQL
轻松入门MySQL:数据库设计之范式规范,优化企业管理系统效率(21)
轻松入门MySQL:数据库设计之范式规范,优化企业管理系统效率(21)
|
21天前
|
存储 SQL 关系型数据库
轻松入门MySQL:加速进销存!利用MySQL存储过程轻松优化每日销售统计(15)
轻松入门MySQL:加速进销存!利用MySQL存储过程轻松优化每日销售统计(15)
|
21天前
|
存储 关系型数据库 MySQL
轻松入门MySQL:优化进销存管理,掌握MySQL索引,提升系统效率(11)
轻松入门MySQL:优化进销存管理,掌握MySQL索引,提升系统效率(11)
|
15天前
|
SQL 缓存 关系型数据库
mysql性能优化-慢查询分析、优化索引和配置
mysql性能优化-慢查询分析、优化索引和配置
80 1
|
21天前
|
存储 关系型数据库 MySQL
MySQL数据库性能大揭秘:表设计优化的高效策略(优化数据类型、增加冗余字段、拆分表以及使用非空约束)
MySQL数据库性能大揭秘:表设计优化的高效策略(优化数据类型、增加冗余字段、拆分表以及使用非空约束)
|
21天前
|
缓存 关系型数据库 MySQL
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
|
1天前
|
SQL Oracle 关系型数据库
下次老板问你MySQL如何优化时,你可以这样说,老板默默给你加工资
现在进入国企或者事业单位做技术的网友越来越多了,随着去O的力度越来越大,很多国企单位都开始从Oracle向MySQL转移,相对于Oracle而言,MySQL最大的问题就是性能,所以,这个时候,在公司如果能够处理好MySQL的性能瓶颈,那么你也就很容易从人群中脱颖而出,受到老板的青睐。
15 1
|
9天前
|
SQL 关系型数据库 数据库
【后端面经】【数据库与MySQL】SQL优化:如何发现SQL中的问题?
【4月更文挑战第12天】数据库优化涉及硬件升级、操作系统调整、服务器/引擎优化和SQL优化。SQL优化目标是减少磁盘IO和内存/CPU消耗。`EXPLAIN`命令用于检查SQL执行计划,关注`type`、`possible_keys`、`key`、`rows`和`filtered`字段。设计索引时考虑外键、频繁出现在`where`、`order by`和关联查询中的列,以及区分度高的列。大数据表改结构需谨慎,可能需要停机、低峰期变更或新建表。面试中应准备SQL优化案例,如覆盖索引、优化`order by`、`count`和索引提示。优化分页查询时避免大偏移量,可利用上一批的最大ID进行限制。
34 3
|
12天前
|
存储 关系型数据库 MySQL
【MySQL实战笔记】 04 | 深入浅出索引(上)-02
【4月更文挑战第9天】InnoDB数据库使用B+树作为索引模型,其中主键索引的叶子节点存储完整行数据,非主键索引则存储主键值。主键查询只需搜索一棵树,而非主键查询需两次搜索,因此推荐使用主键查询以提高效率。在插入新值时,B+树需要维护有序性,可能导致数据页分裂影响性能。自增主键在插入时可避免数据挪动和页分裂,且占用存储空间小,通常更为理想。然而,如果场景仅需唯一索引,可直接设为主键以减少查询步骤。
13 1
【MySQL实战笔记】 04 | 深入浅出索引(上)-02