首页 > 其他分享 >模糊查询下(like)如何使用覆盖索引优化

模糊查询下(like)如何使用覆盖索引优化

时间:2023-03-22 22:34:40浏览次数:52  
标签:index like 覆盖 查询 索引 using 主键


在MySQL中,like ‘string%’可以用到索引,但是like ‘%string%’却会全表扫描。这个是常识,但真的就没有解决方法了吗?有的,要使用到索引覆盖。

什么叫覆盖索引?

  • 解释一: 就是select的数据列只用从索引中就能够取得,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖。
  • 解释二: 索引是高效找到行的一个方法,当能通过检索索引就可以读取想要的数据,那就不需要再到数据表中读取行了。如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫做覆盖索引。
  • 解释三:是非聚集组合索引的一种形式,它包括在查询里的Select、Join和Where子句用到的所有列(即建立索引的字段正好是覆盖查询语句[select子句]与查询条件[Where子句]中所涉及的字段,也即,索引包含了查询正在查找的所有数据)。

总之,不是所有类型的索引都可以成为覆盖索引。覆盖索引必须要存储索引的列,而哈希索引、空间索引和全文索引等都不存储索引列的值,所以MySQL只能使用B-Tree索引做覆盖索引

小试牛刀

CREATE TABLE a1
 (
     id INT AUTO_INCREMENT PRIMARY KEY,
     column_name VARCHAR(20),
     column_type VARCHAR(20)
 );
 CREATE INDEX idx_a1_column_name ON a1(column_name);

模糊查询下(like)如何使用覆盖索引优化_聚集索引

语句1:它没有使用到索引(Extra:using where),意味着全表扫描,理论如此,

语句2:它使用了索引范围查找(type=range)(key=idx_a1_column_name),但是它使用索引方式为二级检索(Extra:Using index condition)还是会有一定的性能消耗的,也有解决办法:针对select的列创建联合索引

语句3:它使用了索引覆盖(Extra:Using index)

结论:

  • using index :使用覆盖索引的时候就会出现
  • using where:在查找使用索引的情况下,需要回表去查询所需的数据
  • using index condition:查找使用了索引,但是需要回表查询数据
  • using index & using where:查找使用了索引,但是需要的数据都在索引列中能找到,所以不需要回表查询数据

有实验证明using index & using where要优于using index condition。

小知识点(原理)

1.啥是回表?

上面讲过如果索引的列在select子句中就不需要回表,索引列也是表,如果索引中包括你需要的列,查询结果就找到了,如果没有你需要的列,索引列中有指针指向表记录的行位置,从表中查询列值

2.二级索引篇

聚簇索引:每个InnoDB表具有一个特殊的索引称为聚集索引。如果您的表上定义有主键,该主键索引是聚集索引。如果你不定义为您的表的主键 时,MySQL取第一个唯一索引(unique)而且只含非空列(NOT NULL)作为主键,InnoDB使用它作为聚集索引。如果没有这样的列,InnoDB就自己产生一个这样的ID值,它有六个字节,而且是隐藏的,使其作为聚簇索引。

二级索引:又称辅助索引、非聚集索引(no-clustered index)。b+tree树结构,然而二级索引的叶子节点不保存记录中的所有列,其叶子节点保存的是<健值,(记录)地址>,非叶子节点存放的记录格式为<键值,主键值,地址>。而聚集索引叶子节点保存保存记录中的所有列,非叶子节点保存的是下一层节点地址。

记录的地址一般可以保存两种形式:

1. 记录的物理地址,页号:槽号:偏移量 
2 . 记录的主键值

innodb引擎是索引组织表,所有记录都放在聚集索引里,因此其辅助索引中的记录地址存放的主键的键值。

读操作

通过二级索引查询记录仅能得到主键值,要查询完整的记录还需要再通过一次聚集索引查询,这种查询方式为书签查找(bookmark lookup)。

写操作:

仅当主键发生改变时,才会更新二级索引。

 

标签:index,like,覆盖,查询,索引,using,主键
From: https://blog.51cto.com/alex/6143469

相关文章

  • 地铁查询系统安卓端团队进度(一)
    1.今天我和团队成员构思了一下安卓端地铁查询系统应该怎么做,探讨了要实现什么样的功能,并进行了设计.2.并且还需要设计一些按钮,并做到一些美化界面的设计3.并且还商量......
  • SQL Server 索引
    索引的简介:索引分为聚集索引和非聚集索引,数据库中的索引类似于一本书的目录,在一本书中通过目录可以快速找到你想要的信息,而不需要读完全书。索引主要目的是提高了SQLServ......
  • 全网最详细中英文ChatGPT-GPT-4示例文档-官网推荐的48种最佳应用场景——从0到1快速入
    目录Introduce简介setting设置Prompt提示Sampleresponse回复样本APIrequest接口请求python接口请求示例node.js接口请求示例curl命令示例json格式示例其它资料下载......
  • 倒排索引
     信息检索--简单易懂的倒排索引(原理+例子)_土豆同学的博客-CSDN博客_倒排索引https://blog.csdn.net/qq_43403025/article/details/114779166倒排索引与全文索引MySQ......
  • elasticsearch RESTful搜索引擎-(java jest 使用[入门])
     elasticsearch简称ESjest好吧下面我介绍下jest(第三方工具)它是ES的java客户端,基于httprestful...jest是开源的 首先看看项目的目录结构我一般习惯了用maven去管理我的......
  • 大数据量实时统计排序分页查询(并发数较小时)
    大数据量实时统计排序分页查询的瓶颈不是函数(count,sum等)执行,不是having,也不是orderby,甚至不是表join,导致慢的原因就在于“数据量太大本身” 化整为零就是将表划分为M......
  • java 微信支付v3 —6.微信支付查询订单API
    正文什么时候会用到这个API?常规情况下,回调接口已经足够我们使用,用户支付成功后,微信会自动调用我们的回调接口进行回调,那么还需要这个API吗?使用场景:微信服务器故障,我们的服......
  • Sql Server中查询数据库所有表及其数据总条数和占用空间
    1、查询某数据库中的所有数据表SELECTname数据表FROMsysobjectsWHERExtype='u'ORDERBYname2、查询某数据库中的所有数据表及其数据总条数SELECTa.name数据表,......
  • C++查询ip归属地(QT)
    以查询ip归属地的例子来学习C++的API接口调用。常见的API接口可能会给出post及get两种访问方法,我们先学习较为简单的get方法。首先是找到相关的接口,如https://ip.userage......
  • [FastAPI-04]查询参数-分页
    fromfastapiimportFastAPIBOOKS=[{"id":1,"title":"book1"},{"id":2,"title":"book2"},{"id":3,"title":"book3"},{"id":4,&qu......