关于数据库:面试官如何优化索引

3次阅读

共计 9596 个字符,预计需要花费 24 分钟才能阅读完成。

大家好,我是🐟老师,明天咱们一起来讨论一下如何优化索引。

文章浏览时长约 15 分钟。

在探讨优化索引前,咱们应该先理解一下数据库中索引的类型,怎么样抉择索引,索引的老本代价有那些,如何衡量性能和老本,索引外部存在的一些优化操作,到最初索引的最佳优化实际等。

对于索引那些繁冗的说法 / 别名

对于索引分类的问题,始终让咱们很头疼,因为索引依据不同的维度,有很多种不同繁冗的说法。如果咱们不懂这些繁冗的说法,那么在面试的时候不晓得面试官在说什么,有可能会一脸懵逼。

从数据结构角度:

  • B+ 树索引:查问效率比拟均匀,个别是 3~4 的 I /O,反对范畴查问,范畴查问快
  • 哈希索引:单条查问快,然而不反对范畴查问,有 hash 碰撞问题
  • FULLTEXT 索引:目前 MyISAM 和 InnoDB 引擎都反对了,分词算法,用于含糊检索字符串
  • R-Tree 索引:用于对 GIS 数据类型创立 SPATIAL 索引,B+ 树多维化

从物理存储角度:

  • 汇集索引 / 聚簇索引:数据文件和索引文件存储在一个文件,也就是索引文件即数据文件,数据文件即是索引文件
  • 非汇集索引 / 非聚簇索引:数据文件和索引文件离开存储,别离在不同的文件
  • 密集索引 / 浓密索引:

    文件中的索引项蕴含搜寻键值 / 索引值和指向磁盘上理论记录的指针。

    每条索引项的行对应一条记录,数据查问速度十分快,然而保护老本大。

    如何定位数据:

    通过二分查找,搜寻值 = 索引项的索引值,就能精确的定位到数据。

  • 稠密索引:

    要求索引字段是依照程序排序的,否则无奈有序索引。

    没有为每条记录建设对应的索引项的行,数据查问速度较慢。

    然而存储空间小,保护成本低。

    如何定位数据:

    通过二分查找,搜寻值 > 索引值中的最大值,而后依据记录所在的记录汇合
    依照偏移量进行程序查找,如果不在以后记录,则持续应用二分法查找。

       直到找到为止。

  • 在 myisam 存储引擎中,不论是什么索引都是非汇集索引 / 非聚簇索引,稠密索引。
  • 在 innodb 存储引擎:有且只有一个汇集索引 / 聚簇索引,密集索引 / 浓密索引,而这个索引就是主键索引。innodb 存储引擎里的一般二级索引是非汇集索引 / 非聚簇索引,稠密索引。

从逻辑角度:

  • 主键索引:应用主键来组织残缺的行数据记录
  • 一般索引:在创立索引时,不附加任何限度条件(惟一、非空等限度)
  • 单列索引 / 单值索引 / 繁多索引:构建索引树的索引列个数为 1(创立索引的字段个数为 1)
  • 多列索引 / 联结索引 / 辅助索引 / 复合索引 / 二级索引:构建索引树的索引列个数超过 1(创立索引的字段个数 > 1)
  • 窄索引:构建索引树的索引列个数为 1~2
  • 宽索引:构建索引树的索引列个数超过 2
  • 惟一索引:构建的索引树外面的索引列的值是惟一的,不存在反复值
  • 非惟一索引:构建的索引树外面的索引列的值是惟一的,存在反复值

浅聊数据库中的索引类型

索引的类型分为四种:
FULLTEXT(全文索引)[理解]:

  • 次要用来查找文本中的关键字,只能在 CHAR、VARCHAR 或 TEXT 类型的列上创立 在 MySQL 中只有 MyISAM 存储引擎反对全文索引。
  • 全文索引容许在索引列中插入反复值和空值。
  • 不过对于大容量的数据表,生成全文索引十分耗费工夫和硬盘空间。

SPATIAL(空间索引)[理解]:

  • 空间索引是对空间数据类型的字段建设的索引
  • 创立空间索引的列必须将其申明为 NOT NULL,空间索引只能在存储引擎为 MyISAM 的表中创立
  • 空间索引次要用于天文空间数据类型 GEOMETRY。这类索引相对来说很少会被用到。

NORMAL(一般索引):

  • MySQL 中最根本的索引类型,放慢系统对数据的访问速度。
  • 没有任何的限度,容许在定义索引的列中插入反复值和空值。

UNIQUE(惟一索引):

  • 惟一索引与一般索引相似,但它的目标不是为了进步访问速度,而是 为了防止数据呈现反复
  • 惟一索引列的值必须惟一,容许有空值。如果是组合索引,则列值的组合必须惟一。

单值索引 - 联结索引 -> 最左前缀准则

从根据创立索引的字段的个数咱们能够分为单值索引和联结索引。
单值索引:依据一个字段来建设索引
联结索引:依据超过一个字段来创立索引
联结索引如图所示:
上面咱们依据 name 和 age 依照程序建设联结索引。
在 B + 树中,会依照第一个索引列 name 进行排序大小,在第一个索引列 name 的雷同的有序的状况下在去排序下一个索引列 age。
当咱们执行 select * from user where name = “Adfhe” and age = 30 的时候

  • 遍历找到 name = “Adfhe” 的节点,而后依据空白指针往下找,依据 age 进行比对
  • 最初获取对应的主键 id,依据主键 id 到主键索引进行回表操作

最左前缀准则:
最左前缀准则这个说法只是针对联结索引的一种建设规定策略。
如果索引蕴含了多个列,那么咱们最好遵循最左前缀准则。
咱们都晓得当咱们建设多个索引列的时候,会依照索引列建设的程序进行构建索引树。最左前缀准则指的是尽量要让查问会从索引的最左列开始匹配,依照每一个建设的索引的程序,依照程序顺次匹配。期间不能跳过两头的某个索引列。且索引匹配严格依照第一个索引开始排序,顺次往后。

假如咱们建设了(name,task,age)的联结索引,依照最左前缀的准则要求:
执行 sql:select * from user where name = “a” and task = “b” and age =18

  • 咱们须要从最左列 name,找到 name 匹配值
  • 而后在 name 雷同的状况根底下,task 有序,而后找到 task 匹配值
  • 而后在 task 匹配的状况根底下,age 有序,而后找到 age 的匹配值

留神:如果咱们没有依照程序顺次去遍历匹配的状况,跳过了两头某一个索引列的匹配,则该索引列后续的程序都是乱的,因为在 B + 树中,联结索引的建设的有序性都是根据上一个索引列为雷同的状况下,以后索引列才有序(这个跟 B + 树的存储构造原理无关)。

假如咱们建设了(name,task,age)的联结索引,不依照最左前缀的准则要求,跳过两头 task 索引:
执行 sql:select * from user where name = “a” and age = 18

  • 咱们须要从最左列 name,找到 name 匹配值
  • 而后在 name 雷同的状况根底下,task 是有序,然而因为咱们不须要查找 task 的值,只能节点往下全副遍历
  • 因为 age 有序的前提是 task 为有序,因为 task 不须要查找指定的值,因而会全副遍历,导致 age 无序

因而这个索引只走了 name 有序,剩下的 age 和 task 都没有被利用到索引树放慢检索效率。

假如咱们建设了(name,task,age)的联结索引,不依照最左前缀的准则要求,跳过两头 age 索引:
执行 sql:select * from user where task = “b” and age = 18

  • 咱们须要从最左列 name,找到 name 匹配值,因为 name 没有指定匹配的值,因而会全副遍历,导致 task 无序
  • 因为 task 无序,则 age 也无序

因而这个索引没有走到任何的列,因为 name 无序,导致 task 无序,age 无序,无奈走索引列。

上面咱们能够一起来尝试做一下以下的题目(面试官最爱问系列):
假如咱们建设了索引(a,b,c)

索引根本读取操作

回表(磁盘随机 I /O)

  • 在 innodb 存储引擎中,由主键索引去组织残缺用户记录数据,而辅助索引来组织其余字段的排序记录。
  • 当咱们查问须要通过辅助索引来查找数据的时候,innodb 存储引擎会先到辅助索引去找到匹配的记录对应的主键。在通过主键到主键索引找到相干的残缺用户记录,这个过程就叫做回表。
  • 因而依据辅助索引来查问数据,须要应用到两颗 B + 树(辅助索引 + 主键索引)。

为什么须要回表,为什么不能把残缺用户记录存储到二级索引呢(用二级索引来组织残缺用户记录数据)?

  • 如果咱们把残缺用户记录存储到二级索引的话,的确是不须要回表,按情理上来讲效率的确会高一些。
  • 然而咱们建设多个索引的状况下,每个索引都存储残缺用户记录的话,会节约大量的存储空间。
  • 其次在我的项目中咱们进行增删改某一条残缺用户记录中的某个字段数据的时候,咱们还须要去保护表中所有的 B + 树的索引叶子节点的数据,可想而知,这个性能很低的。

MRR 多范畴读取(二级索引范畴查问后主键无序,排序后回表)

  • MRR 全名称:Disk-Sweep Multi-Range Read
  • 当表的数据量很大的时候,在二级索引应用范畴查问可能会导致的大量的磁盘随机 I /O(回表导致)。
  • 应用 MRR,能够在扫描索引后,将索引对应的主键 keys 进行排序后,通过有序的主键去拜访主键索引
  • 这样能够缩小对磁盘的随机 I /O,进行对主键索引更多的程序读

在回表中,咱们依据辅助索引中筛选匹配,依据记录的主键值到主键执行回表操作。那么在辅助索引中筛选匹配的主键记录,存储两种状况。第一种状况主键值有序,这种个别是等值匹配查问(例如建设索引 name,那么 name 字段等值匹配雷同的状况,主键 id 是有序的,建设索引 name 其实跟建设索引(name,id)是一个意思)。第二种状况是主键值无序,这种个别是范畴查问。

当咱们每次回表都会去随机读取一个聚簇索引的页面(磁盘随机 I /O)。这些随机 I / O 带来的性能开销比拟大。因而就呈现了 MMR 多范畴读取来进行优化这一步骤。针对于以上第二种状况而言,每次读取一部分的主键值,进行排好序后在对立执行回表操作。这样尽管是随机 I /O,然而有序相连数据,磁盘的页与页之间的寻址就不须要太久。
应用 MMR 多范畴读取,相比每次从辅助索引读取一条主键值,就去回表会缩小一些磁盘随机 I /O。

Mysql 中对于索引的个性

索引下推(单个联结索引过滤数据,缩小回表)

指的是在辅助的联结索引查问的时候,同时过滤字段数据,无效的缩小回表成果的操作

对于辅助的联结索引 (name,age),失常状况依照最左前缀准则。依照 select * from user where name like ‘A%’ and age = 30 这种状况只会走 name 字段索引,然而依据 name 字段过滤完,失去的索引行里的 age 是无序的,无奈很好的利用索引,那么索引下推就呈现了。上面咱们来比照一下有应用索引下推和没有应用索引下推的区别。

在 MySQL5.6 之前的版本,没有索引下推的概念:

  • 首先会依据联结索引(二级索引)匹配合乎 ”A” 结尾的索引节点
  • 依据相干的索引节点对应的主键值进行顺次回表
  • 到主键索引查找对应的残缺的行数据记录,进行数据过滤比照 age 的值是否符合要求

MySQL 5.6 引入了索引下推优化(在索引遍历过程中,对所有字段进行数据过滤比对记录):

  • 首先会依据联结索引(二级索引)匹配合乎 ”A” 结尾的索引节点
  • 同时过滤字段 age 的数据,依据过滤后的索引节点进行回表
  • 到主键索引查找对应的残缺的行数据记录

比照是否应用索引下推:

  • 不应用索引下推,则字段的数据过滤在 回表查问残缺用户记录后进行过滤
  • 应用索引下推,则是在回表前 通过联结索引进行匹配索引值的同时进行字段的数据过滤
  • 因而应用索引下推能够无效的缩小回表次数。回表的次数缩小,磁盘 I / O 也相应缩小,进步了性能。

发问 1: 索引下推只能用在二级索引吗,为什么主键索引没有?
假如主键索引有,那么当咱们回表,到主键索引查找对应的残缺的行数据记录去过滤字段数据。因为主键索引是汇集索引,它的叶子节点蕴含了残缺的行记录。依照咱们这种玩法跟不应用索引下推的成果一样,而且并没有缩小回表,也查问了一样多的行数据。

发问 2: mysql 肯定会应用索引下推吗?
在 mysql 中,查问优化器会进行不同查问形式的老本估算来决定是否是否索引下推。

  • 如果查问的过滤的后果集太大(并没有显著的缩小回表的次数),不肯定会应用索引下推,可能不应用索引下推的查找速度更快。
  • 如果查问的过滤后果集很小(无效的缩小回表次数),则可能会应用索引下推。

咱们晓得索引下推是联结索引没法走全副索引列,所以须要过滤数据,如果这样的话,咱们能够依据业务需要建设一个更好的索引,让他们全副走索引,就不存在数据过滤问题,性能更高。

索引合并(多个二级索引记录的主键 id 过滤,缩小回表)

指的是将多个索引的后果集的主键进行合并,缩小回表次数

假如咱们建设了 name 和 age 的二级索引,执行 select * from user where name = “Adfhe” and age = 30

  • 依据 name 二级索引从 B + 树中取出 name = “Adfhe” 相干的记录(索引列 + 主键)
  • 依据 age 二级索引从 B + 树中取出 age = 30 相干的记录(索引列 + 主键)
  • 因为链接符是 and,所以依据两局部索引的过滤记录依照主键取交加
  • 依据交加的 id = 1 进行到主键索引进行回表操作,依据主键查问残缺行数据记录

对于索引合并,依据 sql 语句的连接符,and 则取交加(Intersection),or 则取并(Union)。目前以后案例演示的是 and 取交加

一般索引合并须要满足的条件

1. 用于等值查问

对于联结索引来说,在联结索引中的每个列都必须等值匹配,不能呈现只匹配局部列的状况。这种状况下,查问进去的索引的主键 key 是有序的。

假如查问应用索引合并的形式从 a 和 b 这两个二级索引中获取到的主键值别离是:
从 a 中获取到曾经排好序的主键值:1、3、5
从 b 中获取到曾经排好序的主键值:2、3、4
那么求交加的过程就是这样:

  • 一一取出这两个后果集中最小的主键值,如果两个值相等,则退出最初的交加后果中
  • 否则抛弃以后较小的主键值,再取该抛弃的主键值所在后果集的后一个主键值来比拟,直到某个后果集中的主键值用完了,工夫复杂度是 O(n)。

取出两个后果集的最小主键值:1,2,抛弃最小的主键值 1,a 后果集为 3,5,b 后果集为 2,3,4
获取 a 后果集中的最大主键值 5 比照 b 后果集中的 2,不雷同
获取 a 后果集中的主键值 3 比照 b 后果集中的 2,不雷同
进行下一轮 b 后果集中的 3 进行比照,依照此程序比照

然而如果从各个二级索引中查问出的后果集并不是依照主键排序的话,那就要先把后果集中的主键值排序完再来做上边的那个过程,就比拟耗时了。
依照有序的主键值去回表取记录有个专有名词,叫:Rowid Ordered Retrieval,简称 ROR

2. 主键列能够是范畴查问
因为如果依照联结索引,进行排序的话,获取到的主键 key 是有序的,咱们能够依据主键列的范畴查问(例如 id > 5),进行过滤主键

非凡的 sort 索引合并(须要将无序转为有序)

绝对于一般的索引合并(二级索引查问之后的主键都是有序的),当多个二级索引的索引列是范畴查问的话,得进去的主键 id 是无序的,那么会将无序的主键 id 进行排序完,后进行索引取交加或者并集,最初在回表。非凡的索引合并比一般的索引合并多了一步二级索引记录的主键值排序的过程。

满足了索引合并的条件就会触发索引合并吗?
当查问优化器依据二级索引中获取的记录数比拟少,通过索引合并后进行拜访的代价比全表扫描更小时才会应用索引合并。

比照是否应用索引合并

不应用索引合并,只应用一个索引:
依照咱们目前建设的索引和查问的 sql 语句,如果咱们不应用索引合并只是读取一个索引,那么咱们须要依据 name 二级索引过滤数据匹配 name 的值后的所有主键 id,依据主键 id 到主键索引进行回表,查问残缺行数据记录。之后须要在进行过滤一遍 age 的值(单个索引查问 + 回表过滤查问条件)

应用索引合并,多个二级索引取交加:
依照不同的筛选条件读取对应的二级索引,将多个索引的主键值取交加,最初进行回表操作(多个二级索引查问过滤主键 + 回表)

应用联结索引代替索引合并

大部分应用索引合并的起因是多个二级索引为单值索引,所以须要进行主键的合并。如果咱们把索引列都放在一起,建设一个联结索引,间接应用联结索引就完事了。应用联结索引又快又好,不须要像索引合并一样读取多颗 B + 树,而后合并后果!!!

发问 1:哪种形式性能更优?

  • 应用多个二级索引能够缩小回表的次数,然而查问多个二级索引比查问一个二级索引的性能要慢。
  • 读取二级索引的操作是程序 I /O,而回表操作是随机 I /O。程序 I / O 是比随机 I / O 要快几个数量级。对于哪种性能更优没有相对的说法,这取决于所需回表的次数有多少,回表次数越多,随机 I / O 越多越慢。

单索引老本:一个索引的检索耗费 + 回表耗费
多索引老本:多个索引取交加或者并集的耗费 + 回表耗费

  • 如果只读取一个索引的回表的次数很多,且多个二级索引取交加的回表次数很少。且回表带好的性能耗费 > 二级索引取交加的性能耗费,那么索引合并的性能更优。
  • 如果只读取一个索引的回表的次数很少,且回表带好的性能耗费 < 二级索引取交加的性能耗费,那么只应用一个索引的性能更优。

    谈谈索引的老本

    空间老本(内存空间)

    每当咱们建设一个索引,就要构建一颗对应的 B + 树,每一棵 B + 树的每一个节点都是一个数据页,一个页默认会占用 16KB 的存储空间,一棵很大的 B + 树由许多数据页组成会占据很多的存储空间。

    工夫老本(保护索引)

    B+ 树每层节点都是依照索引列的值从小到大的程序排序而组成了双向链表。而节点外部的记录依照索引列的值从小到大的程序而造成了一个单向链表。每次对表中的数据进行增、删、改操作时,都须要去保护各个 B + 树。因为增、删、改操作可能会对节点和记录的排序造成毁坏,所以存储引擎须要额定的工夫进行一些记录移位,页面决裂、页面回收的操作来保护好节点和记录的排序,这些保护操作也会产生性能影响。

    高性能索引策略 / 索引的最佳实际

    探讨话题前的思考: 有索引肯定会走索引吗?
    有索引不肯定会走索引,因为 mysql 会依据查问优化器,对表中的数据量多少,筛选匹配后的数据量多少,全表扫描,应用各个索引的老本,回表的记录数多少等等进行老本剖析,以此来抉择最优的形式来执行 sql。

正确地创立和应用索引是实现高性能查问的根底,上面咱们来看看如何创立高性能的索引:

1. 抉择区分度高的字段建设索引

索引字段的区分度 / 离散度越高,则检索的次数越少。如果字段的区分度不高,可能整个查问下来会查问超过一半多的数据,同时这样索引页外部的用户分组没法疾速筛选数据,这样也就没法疾速利用二分查找的算法。此外区分度高的索引能够利用好二分查找算法,检索性能更高,在检索数据时过滤掉更多的数据,缩小回表的次数。

 那么如何判断表内某些字段的离散度高不高呢?咱们能够通过数据库表字段不反复的个数除于所有行数来计算,值越大阐明离散度越高。
SELECT COUNT(DISTINCT 字段) / COUNT(*)  from 表;

2. 在容许的状况下,尽量抉择占用存储空间少的字段建设索引

  • 数据类型越小,在查问时进行的比拟操作越快(CPU 档次)
  • 数据类型越小,索引占用的存储空间就越少,在一个数据页内就能够放下更多的记录,从而缩小磁盘 I / 0 带来的性能损耗,也就意味着能够把更多的数据页缓存在内存中,从而放慢读写效率。

3.where 语句中常常被应用到的字段应该建设索引,分组字段或排序字段应创立索引,多表连贯字段应该创立索引

只为呈现在 where 子句中的列、连接子句中的连贯列创立索引,而呈现在查问列表中的列个别就没必要建设索引了,除非是须要应用笼罩索引。又或者为呈现在 order by 或 group by 子句中的列创立索引。

4. 更新频繁的字段不适宜建设索引

如果这个字段更新很频繁,那么须要常常去保护这个字段建设的相干索引,最坏的后果可能会导致页决裂,合并等,性能开销很大。

5. 建设索引遵循最左前缀准则

遵循最左前缀准则,可能让查问条件尽最大可能的命中更多的索引列,最大化的命中更多索引列。

6. 尽量应用前缀索引

有时候咱们须要对一些字符串很大的字段建设索引,这会让索引变的很大,内存的开销很大,cpu 操作大的数据也很慢且一个数据页存储的字段数据更少,查问更慢。咱们能够将字段的开始的局部字符建设索引,这样大大减少了内存开销,也进步了索引的效率。抉择应用前缀索引的同时,也失去了字段的区分度。因而咱们要保障前缀索引有足够高的区分度,同时也不能保障索引太大。
咱们能够通过计算,来找到适合建设的前缀长度。通过如下 sql 一直的调整前缀长度的大小,来查看离散度的大小的增幅变动,从而来找到最适宜的前缀长度大小。

SELECT COUNT(DISTINCT LEFT(字段, 前缀长度))/COUNT(*)  FROM 表;

7. 尽量设计多列索引,防止创立反复的索引以及删除未应用的索引

  • 尽量设计多列索引,依据索引列的区分度,查问字段的频率,sql 进行衡量索引列的排序地位。
  • 当联结索引蕴含了单值索引,则单值索引反复,例如索引(a,b)和索引 a,则索引 a 反复删除即可
  • 在我的项目中可能会因为 sql 的查问慢须要进行优化改变,未免会呈现某些索引忽然用不到的状况,咱们应该删除,缩小带好的内存开销。

8. 尽可能设计三星索引

三星索引由《高性能 MySQL》作者提出的一个概念,如果满足了三星索引则能够认为这是一个性能很高的索引

第一星(缩小数据检索范畴):如果一个查问相干的索引行是相邻的或者至多相距足够凑近的话,必须扫描的索引片宽度就会缩至最短,也就是说,让索引片尽量变窄,也就是咱们所说的索引的扫描范畴越小越好。尽量将 where 的等值查问,区分度高的列放在后面。

第二星(排序星,索引依照查问语句中 order by 排序):当查问须要排序,order by 中的排序和索引程序统一,它可能缩小耗时的文件排序。咱们能够依照 sql 给 order by 相干的字段依照程序退出索引列中。

第三星(宽索引星,笼罩索引):索引行蕴含查问语句中所有的列。这样就不须要回表操作(磁盘随机 I / O 慢),只须要拜访一个二级索引即可。咱们能够将相干的查问列退出到索引当中去。
在大部分的状况下,咱们不能同时满足三星,因而咱们须要在三星外面做衡量。

select name,age,city from user where name="aaa" and age = 20;

最佳的索引是建复合索引 (name, age, city),这是一个三星索引。
第一星:很显著 name 的区分度比 age 高,为了过滤尽可能多的行,须要把把选择性高的索引放在后面 name,age。缩小索引片的大小以缩小须要扫描的数据行
第二星:也就是说,当通过了 name,age 的筛选之后,筛选进去的行自身就是已排序的 city。防止排序,缩小磁盘 IO 和内存的应用;
第三星:通过宽索引实现索引笼罩,防止回表进行磁盘随机 I/O

在一些简单的查问中,咱们没法同时满足三星,只能在三星之中做衡量。

SELECT id, name, age FROM user
WHERE age BETWEEN 18 AND 25
  AND city = "aaa"
ORDER BY name;

在这个状况下,city 是等值索引,为了缩小索引的检索范畴,咱们须要建设索引(city,age),此时取得一星。为了获取第三颗星,咱们须要建设索引(city,age,name)。然而因为 age 是范畴查问,导致 name 是是无序的,所以没法满足第二颗星。为了防止内存排序操作,咱们更改索引为(city,name,age),满足了第二颗星和第三颗星。因而咱们须要在第一颗星和第二颗之间做抉择。

因而大部分状况(简单查问)下,咱们须要在三颗星之间进行抉择。依照惯例的思维来说,咱们个别优先满足第三颗星,缩小回表的随机 I /O,性能晋升最大。其次优先满足第一颗星,缩小大部分的数据检索范畴,让下一次查问缩小数据量更少。当然这也不是相对的标准答案,须要查看以后查问数据的数据量,假如满足第一颗星能筛选出大部分的数据的性能大于满足第二颗星的排序的性能,则抉择第二颗星。须要依据查问的重点。

🎣

发问 1: 如何设计一个高性能索引

  1. 抉择区分度高的字段建设索引
  2. 在容许的状况下,尽量抉择占用存储空间少的字段建设索引
  3. where 字句中常常被应用到的字段应该建设索引,分组字段或排序字段应创立索引,多表连贯字段应创立索引
  4. 更新频繁的字段不适宜建设索引
  5. 建设索引遵循最左前缀准则
  6. 尽量应用前缀索引
  7. 尽量设计多列索引,防止创立反复的索引以及删除未应用的索引
  8. 尽可能设计三星索引

本文由 mdnice 多平台公布

正文完
 0