Mysql索引的常见问题

1.Mysql索引方面常见问题

1.索引的优点和缺点

优点:

  • 可以大大加快数据的检索速度

缺点:

  • 时间方面:创建索引和维护索引需要消耗时间
  • 空间方面:索引需要占物理空间

2.哪些情况下需要创建索引

  1. 主键自动建立唯一索引
  2. 频繁作为查询条件的字段
  3. 多表关联查询中的关联字段
  4. 排序的字段
  5. 频繁查找的字段,需要覆盖索引
  6. 查询中统计或者分组字段

3.哪些情况下不需要创建索引

  1. 表记录太少
  2. 经常进行增删改查操作的字段
  3. where条件里使用频率不高的字段

4.创建索引的几种方式

  1. 创建表时添加索引
  2. 使用alter table命令
  3. 使用create index命令

5. mysql有几种索引类型

  1. fulltext 全文索引
  2. hash 哈希索引
  3. btree b树索引
  4. rtree r树索引

6.为什么索引结构默认使用b+tree,而不是btree,二叉树,红黑树?

  1. btree:因为btree不管叶子节点还是非叶子节点,都会保存数据,这样导致在非叶子节点中能保存的指针数量变少,指针少的情况下要保存大量的数据,只能增加数的高度,导致IO操作变多,查询性能贬低
  2. 二叉树:树的高度不均匀,不能自平衡,查找效率和树的高度有关,IO代价高
  3. 红黑树:树的高度随着数据量的增加而增加,IO代价高
  4. 总的来说,影响mysql查找性能的主要还是磁盘IO的次数,大部分是刺头移动到指定磁道的时间花费,树越高,IO代价越高,查询时间越长

7.hash索引和btree索引的优缺点

优点

  1. 单条数据查询时,hash索引查询时间复杂度为O(1),b数索引时间复杂度为O(logN)。

缺点

  1. hash索引只适合等值查询,但是无法进行范围查询
  2. 哈希索引没有办法利用索引完成排序
  3. 哈希索引不支持联合索引的最左匹配规则
  4. 如果有大量重复键值的情况下,哈希索引的效率会很低,因为存在哈希碰撞

8.索引种类

  1. 普通索引:提高查询速度
  2. 唯一索引:提高查询速度 + 列值唯一 + 可以为null
  3. 主键索引:提高查询速度 + 列值唯一 + 不可以为null
  4. 组合索引:多个字段组合的索引,效率大于索引合并
  5. 全文索引:对文本内容分词搜索

9.为什么建议使用主键自增索引?

由于b+树是有序的,如果不是自增,那么需要将下面的叶子节点进行移动,腾出位置来插入数据,这样就会比较耗时间,如果刚好数据满了,还需要进行页分裂操作。
但是如果我们的主键是自增的,每次插入的ID都会比前面的大,那么我们每次只需要在后面插入就行,不需要移动位置,分裂等操作,这样就可以提高性能

10.b+tree的叶子节点可以存哪些东西?两者的区别是什么?

innodb的b+tree可能存储的是整行数据,也有可能是主键的值。
如果索引的叶子节点存储了整行数据的主键索引,也被称为聚簇索引。
如果索引的叶子节点存储了主键的值的非主键索引,也被称之为非聚簇索引。

11.那么聚簇索引(主键索引)和非聚簇索引(非主键索引),在查询数据的时候有区别吗?为什么?

聚簇索引查询更快,因为聚簇索引的叶子节点直接就是我们要查询的整行数据了。而非主键索引的叶子节点是主键的值,查到主键的值之后,还需再通过主键的值进行一次查询。

12.非主键索引是否一定需要回表查询?

如果是覆盖索引就不需要回表。覆盖索引(covering index)指一个查询语句的执行只用从索引中就能够取得,不必从数据表中读取,也可以称之为实现了索引覆盖。

13.何时使用聚簇索引和非聚簇索引?

动作使用聚簇索引使用非聚簇索引
列经常被分组排序YY
返回某范围内的数据YN
一个或极少不同值NN
小数目的不同值YN
大数目的不同值NY
频繁更新的列NY
外键列YY
主键列YY

14.创建联合索引的时候,联合索引多个字段顺序是如何选择的呢?为什么?

按照识别度由高到低一次排序,为了最左前缀匹配。
当创建一个key1、key2、key3的联合索引时,相当于创建了key1、key1-key2、key1-key2-key3三个索引。

15.mysql5.6对索引做什么优化?

index Condition Pushdown 索引下推

16.如何知道有没有走索引查询?

可以通过explain查询sql语句的执行计划,通过执行计划来分析索引使用情况。

17.explain执行计划中你关注哪些字段?

  1. type:表的链接类型(const > eq_ref > ref > range > index > all)
  2. key: 表实际使用的索引
  3. key_len:索引字段的字节数,字符长度*3 ,变长类型+2,可null+1
  4. rows:扫描出来的行数(估算的行数)
  5. extra:执行情况和描述说明

18.什么情况下明明创建了索引,但是执行的时候并没有通过索引?

  1. like通配符在前面
  2. or左右两边有非索引列
  3. 使用了not、not in 、not like等负向查询
  4. 索引字段可以为null,查询使用了is null 或者is not null
  5. 隐式类型转换
  6. 索引列使用了内置函数
  7. 对索引列直接运算
  8. 违背联合索引最左匹配原则
  9. mysql优化器的最终选择

2.mysql四种索引类型的区别以及适用场景

1.fulltext

即全文索引,目前只有MyISAM引擎支持。其可以在ceate table、alter table、create index使用,不过目前只有char、varchar、text列上可以创建全文索引。值得一提的是,在数据量较大的时候,先将数据放入一个没有全局索引的表中,然后再用create index 创建fulltext索引,要比先为一张表建立fulltext索引然后再将数据写入的速度快很多。

2.hash

hash是一种key->value形式的键值对,如数学中的函数映射,允许多个key对应相同的value,但不允许一个key对应多个value。正式由于这个特性,hash很适合做索引,为某一列或几列建立hash索引,就会利用这一列或几列的值通过一定的算法计算出一个hash值,对应一行或几行的数据。在java语言中,每个类都有自己的hashcode方法,没有显示定义的都继承自object类。该方法使得每一个对象都是唯一的,在进行对象间equals比较,和序列化传输中起到了很重要的作用。hash的生成方法有很多种,足可以保证hash码的唯一性。
由于hash索引可以一次定位,不需要像树形索引那样逐层查找,因此具有极高的效率。那为什么还需要其他的树形索引呢?
hash索引有以下问题

  1. hash索引仅仅能满足 = ,in , <=>等精确查询,不能使用范围查询。
    由于hash索引比较的是进行hash运算之后的hash值,所以它只能用于等值的过滤,不能用于基于范围的过滤,因为经过相应的hash算法处理之后的hash值的大小关系,并不能保证和hash运算前完全一样。
  2. hash索引无法被用来避免数据的排序操作。
    由于hash索引中存放的是经过hash计算之后的hash值,而且hash值的大小关系并不一定和hash运算前的键值完全一样,所以数据库无法利用索引的数据来避免任何排序运算
  3. hash索引不能利用部分索引键查询
    对于组合索引,hash索引在计算hash值的时候是组合索引键合并后再一起计算hash值,而不是单独计算hash值,所以通过组合索引的前面一个或几个索引键进行查询的时候,hash所以也无法被利用。
  4. hash索引在任何时候都不能避免表扫描
    hash索引是将索引键通过hash运算之后,将hash运算结果的hash值和所对应的行指针信息存放于一个hash表中,由于不同索引键存在相同的hash值,所以即使取满足某个hash键值的数据的记录条数,也无法从hash索引中直接完成查询。还是要通过访问表中的实际数据进行相应的比较,并得到响应的结果。
  5. hash索引遇到大量hash值相等的情况后性能并不一定就会比btree索引高。
    对于选择性比较低的索引键,如果创建hash索引,那么将会存在大量记录指针信息存于同一个hash值相关联。这样要定位某一条记录时就会非常麻烦,会浪费多次表数据的访问,而造成整体性能地下。

3.btree

btree索引就是一种将索引值按一定的算法,存入一个树形的数据结构中。每次查询都是从数的入口root开始,依次遍历node,获取叶节点。
btree在myisam里的形式和innodb稍有不同。
在innodb里,有两种形态:一是primary key形态,其叶节点里存放的是数据,而且不仅存放了索引键的数据,还存放了其他字段的数据。二是secondary index,其叶节点和普通的btree差不多,只是还存放了指向主键的信息。
在myisam里,主键和其他的并没有太大的区别。不过叶节点里存放的不是主键的信息,而是指向数据文件里的对应数据行的信息

4.rtree

rtree在mysql很少使用,仅支持geometry数据类型,支持该类型的存储引擎只有mysiam、bdb、innodb、ndb、Archive几种。
相对于btree、rtree的优势在于范围查找。

5.各种索引的使用情况

  1. 对于btree这种mysql默认的索引类型,具有普遍的适用性
  2. 由于fulltest对中文支持不是很好,在没有插件的情况下,最好不要使用。其实,一些小的博客应用,只需要在数据采集时,为其建立关键字列表,通过关键字索引,也是一个不错的方法。
  3. 对于一些搜索引擎级别的应用来说,fulltext同样不是一个好的处理方法,mysql的全文索引建立的文件还是比较大的,而且效率不是很高,即便是使用了中文分词插件,对中文分词支持也只是一般。真要碰到这种问题,Apache的Lucene或许是好的选择。
  4. 正式因为hash表在处理较小数据量时具有无可比拟的优势,所以hash索引很适合做缓存。

3.索引下推(Index Condition Pushdown)

不使用索引条件下推优化时的查询过程:
获取下一行,首先读取索引信息,然后根据索引将整行数据读取出来。然后通过where条件判断当前数据是否符合条件,符合返回数据
使用索引下推优化时的查询过程
获取下一行的索引信息。 检查索引中存储的列信息是否符合索引条件,如果符合将整行数据读取出来,如果不符合跳过读取下一行。 用剩余的判断条件,判断此行数据是否符合要求,符合返回数据。
使用场景

  1. 非聚簇索引,聚簇索引已经有整行数据,不需要回表
  2. 减少回表次数,特别对于like通配符来说,减少效果明显

如何判断
使用explain进行分析时,如果Extra显示Using index condition,说明使用了索引下推

4.图解为什么建议使用自增长主键作为索引

结合b+tree的特点,自增主键时连续的,在插入过程中尽量减少页分裂,即使要进行页分裂,也只会分裂很少的一部分。并且能减少数据的移动,每次插入都是插入到最后。总之就是减少分裂和移动的频率。

插入连续的数据:
在这里插入图片描述

插入不连续的数据
在这里插入图片描述

5.hash索引、btree索引、b+tree索引存储示例图

1.hash索引

在这里插入图片描述

2.btree索引

在这里插入图片描述

3.b+tree索引

在这里插入图片描述

6.思维导图在这里插入图片描述

<think>嗯,用户想了解Excel中的VLOOKUP函数的用法和参数含义。首先,我需要回忆一下VLOOKUP的基本结构。VLOOKUP是垂直查找函数,用于在表格的首列查找指定的值,然后返回该行中指定列的数据。它的四个参数分别是查找值、表格范围、列索引号和匹配模式。 接下来,我得确认每个参数的具体作用。第一个参数是lookup_value,也就是用户要查找的值,比如产品ID或者姓名。第二个参数是table_array,即查找的范围,这里要注意的是,查找值必须位于这个范围的第一列,否则函数无法正确工作。第三个参数是col_index_num,也就是用户想要返回的数据在表格范围中的第几列,这个列数是从表格范围的第一列开始算起的,不是整个工作表的列。第四个参数是range_lookup,决定是精确匹配还是近似匹配,通常用FALSE或0来指定精确匹配,避免错误。 然后,用户可能需要一个具体的例子来理解如何使用。比如,假设有一个产品价格表,用户想根据产品ID查找对应的价格。这时候,VLOOKUP就可以在ID列查找,然后返回价格列的数据。同时,要提醒用户注意表格范围最好使用绝对引用,比如$A$2:$C$100,这样在拖动公式时范围不会变化。 可能遇到的问题也需要考虑。比如,如果查找值不在表格的第一列,或者列索引号超过了表格的列数,函数会返回错误。此外,数据格式不一致也可能导致问题,比如查找值是数字,而表格中是文本格式的数字,这时候需要统一格式。还有,当出现#N/A错误时,可能是查找值不存在,或者匹配模式设置不正确,需要检查参数是否正确。 用户可能还会问到如何避免常见的错误,比如部分数据匹配出错的情况。这时候需要检查是否有多余的空格,或者数据格式不一致,或者表格范围没有锁定导致拖动时偏移。此外,XLOOKUP作为VLOOKUP的升级版,可能在某些情况下更方便,比如可以向左查找或者返回多列数据,这也是可以提及的内容。 最后,整理步骤,从基础语法到参数说明,再到具体案例,逐步引导用户理解如何使用VLOOKUP函数。同时,提供常见错误和解决方法,帮助用户在实际应用中避免问题。如果有必要,还可以比较VLOOKUP和其他查找函数的区别,比如HLOOKUP或XLOOKUP,但根据用户的问题,主要集中在VLOOKUP本身即可。</think>### Excel VLOOKUP函数详解 #### 一、基础语法与参数说明 VLOOKUP函数的语法为: $$=VLOOKUP(lookup\_value, table\_array, col\_index\_num, [range\_lookup])$$ 包含4个参数: 1. **lookup_value**(必填):要查找的值(如单元格引用或具体值) 2. **table_array**(必填):包含数据的表格范围(必须包含查找列和返回列) 3. **col_index_num**(必填):返回值所在列的序号(从table_array第一列开始计数) 4. **range_lookup**(可选):匹配类型 - `TRUE`/`1`:近似匹配(默认值,需数据升序排列) - `FALSE`/`0`:精确匹配(常用选项) [^1][^2] #### 二、使用步骤演示(工资表查询案例) 假设需要根据员工编号查询工资: 1. 建立查询单元格(如`B12`) 2. 输入公式: ```excel =VLOOKUP(A12, $A$2:$D$100, 4, 0) ``` - `A12`:待查询的员工编号 - `$A$2:$D$100`:锁定数据区域(绝对引用) - `4`:返回第4列(工资列) - `0`:精确匹配 [^2][^3] #### 三、常见错误与解决方法 | 错误现象 | 原因 | 解决方案 | |---------|------|---------| | #N/A | 查找值不存在 | 检查数据源或改用`IFERROR`容错 | | #REF! | 列序号超出范围 | 确认col_index_num ≤ 表格列数 | | 部分匹配失败 | 数据格式不一致 | 统一数值/文本格式 | | 结果错位 | 表格未锁定 | 使用`$`符号固定区域引用 | [^3][^4] #### 四、进阶技巧 1. **多条件查询**: 使用辅助列合并多个条件字段 ```excel =VLOOKUP(A2&B2, $D$2:$F$100, 3, 0) ``` 2. **通配符匹配**: `"*"`匹配任意字符,`"?"`匹配单个字符 ```excel =VLOOKUP("张*", $A$2:$C$100, 3, 0) ``` 3. **跨表查询**: 引用其他工作表数据 ```excel =VLOOKUP(A2, Sheet2!$A$2:$D$100, 4, 0) ``` [^1][^4]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值