前情引子

in 会不会走索引?很多人肯定会回答、废话、如果命中了索引、那肯定会走。

其实我和大多数人一样、一开始也是这么想的、直至有一个血淋淋的案子让我有所改观、有所思考。

背景介绍

业务的工单表、我们分了64张、以userId作为分表键、业务实际场景中未使用到搜索引擎、主要是一些B端业务。

业务有一个场景是使用userId作为条件 使用in语句查询工单数据。

这里分析一下、

  • 第一个userId作为分表键作为查询条件是合理的
  • 第二个、该业务场景下的SQL为userId字段添加了索引、是考虑到的

实际发生问题

该需求上线之后、我们发现个别B端使用人员、他需要查询userId为5w左右的条件查询、经日志查询该查询的耗时大概在35S左右、正常查询都是3S以内。当问题发生的时候、我就在分析、in 到底有没有走索引、如下

  • 5w/64张表=781 个 假设按照平均分配  每个表的in包含的个是不足1k
  • 第二个每张分表其实都是添加了索引的
  • 数据库的监控服务没有查询到有慢SQL出现

综合以上初步判断、这么小的量、如果命中索引、那不该需要查询这么长的时间。

解决方案

既然出现了问题、那肯定是要解决方案的、思考的角度如下:

  1. 分表情况下、无法使用大家熟悉的explain 语句 直接查询数据库、让数据库告诉你有没有使用索引、当然、如果你指定其中一张分表还是可以使用explain语句的
  2. 数据库分表、DB的操作实际上是将每张表的查询结果出来之后、全部load到内存聚合之后再返回给实际调用他的Java服务的
  3. 假设这里命中了索引、基于第二点那慢的另一个因素可能就是DB服务器内存被打满了

这里我基于第三点的假设、对于业务代码进行了改造

使用in条件进行查询

限制了每次查询数据库in所包含的userId个数最多是5000个、即时就是我们经常说的批量查询、这样子做、最大量的5w就会分成10批去查询数据库、结果再聚合。而分到每张表的in包含的个数、按平均情况就只有了78个左右了、改成这种写法、从宏观的角度、就是把DB的一部分压力转移到业务服务器上。

结果如何

新的代码拿到正式环境进行验证之后、使用同样的用户进行测试、in的条件个数仍是5w、但最后的查询结果仅在3S左右就返回了、完成了从35S到3S的质的飞跃的提升。

对于解决问题而言、我们已经是成功的Solver、We are white cat or black cat.

But 这里有仍有两个疑问、

批次的数量具体是哪个值合适2k or 5k、这里我的5k值是与我的正常业务的水平相一致的、所以我说是适合我的、但并不是适合所有场景、所有人。

从最后的结果提升来看、我更倾向于改造后的代码既是走了索引、也为DB减少了压力、才会有这么高的性能提升。

我请教一位现世高人

  • 索引的类型和质量:B-TREE、不需要回表查询、完全命中。
  • in条件值的分布:分布均匀可能会使用到索引
  • 成本估算:MYSQL的查询优化器会基于统计信息对不同的执行计划进行成本估算?全表嫂 or 还是用索引比较合适呢?
  • 系统配置和资源限制:innodb-buffer-pool-size?系统的资源使用情况 都会影响执行计划的选择
  • 数据库的版本和配置:5.5及以上查询优化器对in操作进行了优化、但仍旧不能保证。

MYSQL DQL in 到底会不会走索引&in 范围查询引发的思考。的更多相关文章

  1. varchar int 查询 到底什么情况下走索引?

    一个字符类型的.一个int类型的,查询的时候到底会不会走索引,其实很多工作了几年的开发人员有时也会晕,下面就用具体事例来测试一下. 1.  准备工作 先准备2张表,以备后续测试使用. 表1:创建表te ...

  2. MySQL实现强制查询走索引和强制查询不缓存

    0.表结构如下:(包含两个索引) Create Table: CREATE TABLE `user` ( `userID` ) NOT NULL, `userCode` ) DEFAULT NULL, ...

  3. MySQL中使用IN会不会走索引

    结论:IN肯定会走索引,但是当IN的取值范围较大时会导致索引失效,走全表扫描 navicat可视化工具使用explain函数查看sql执行信息 场景1:当IN中的取值只有一个主键时 我们只需要注意一个 ...

  4. 强制MySQL查询走索引和强制查询不缓存

    有些情况下,表中创建了索引但是EXPLAIN的查看执行计划的时候发现并没有走索引.是因为优化器认为该语句不使用索引效率更好. 当然也可以强制走索引.类似: SELECT uid,uname FROM ...

  5. MySQL进阶篇(03):合理的使用索引结构和查询

    本文源码:GitHub·点这里 || GitEE·点这里 一.高性能索引 1.查询性能问题 在MySQL使用的过程中,所谓的性能问题,在大部分的场景下都是指查询的性能,导致查询缓慢的根本原因是数据量的 ...

  6. mysql中关于关联索引的问题——对a,b,c三个字段建立联合索引,那么查询时使用其中的2个作为查询条件,是否还会走索引?

    情况描述:在MySQL的user表中,对a,b,c三个字段建立联合索引,那么查询时使用其中的2个作为查询条件,是否还会走索引? 根据查询字段的位置不同来决定,如查询a,     a,b    a,b, ...

  7. Mysql数据库索引IS NUll ,IS NOT NUll ,!= 是否走索引

    声明在前面 总结就是 不能单纯说 走和不走,需要看数据库版本,数据量等 ,希望不要引起大家的误会,也不要被标题党误导了. 1 数据库版本: 2 建表语句 CREATE TABLE s1 ( id IN ...

  8. 如何根据执行计划,判断Mysql语句是否走索引

    如何根据执行计划,判断Mysql语句是否走索引

  9. Mysql: 强制走索引:mysql between 日期索引 索引问题-日期索引使用

    Mysql: mysql between 日期索引 索引问题-日期索引使用 表结构: dep_date dep arr 联合索引: ind_coll_date_route  (dep_date ,de ...

  10. MYSQL DQL语句(基础)

    MySQL引入 数据库的好处 持久化数据到本地 可以实现结构化查询,方便管理 数据库的相关概念 DB:数据库(database):存储数据的"仓库",它保存了一系列有组织的数据. ...

随机推荐

  1. java学习之旅(day.01)

    Markdown学习 标题 一级标题:#空格+标题名字 二级标题:##空格+标题名字 三级标题:###空格+标题名字 字体 粗体:两边都加两个** Hello,world 斜体:两边都加一个* Hel ...

  2. 【C#】字符串按条件替换关键字

    private string MyReplace(string json, string keyWord, string newWord, Func<string, string, bool&g ...

  3. webview2 示例 Samples Selenium

    https://github.com/MicrosoftEdge/WebView2Samples https://learn.microsoft.com/zh-cn/microsoft-edge/we ...

  4. numpy基础--线性代数

    以下代码的前提:import numpy as np 线性代数(如矩阵乘法.矩阵分解.行列式以及其他方阵数学等)是任何数组库的重要组成部分.numpy提供了一个用于矩阵乘法的dot函数(既是一个数组方 ...

  5. node child_process模块exec

    child_process是Node.js自带的核心模块之一,无需额外安装即可使用. child_process模块提供了创建子进程的功能,可以在Node.js中执行外部命令.脚本文件等,并与其进行交 ...

  6. vue导航固定 吸顶效果

    吸顶效果 如何得到滚动条滚动的距离,document.documentElement.scrollTop 通过onscroll事件来完成滚动事件监听,达到吸顶值后,进行样式更换

  7. sql数据的操作

      /*             数据的写入                 名称 : 库名 表名 字段名 用 反引号包裹                 数据 : 字符串数据使用单引号包裹      ...

  8. IDEA:java: Compilation failed: internal java compiler error

    java: Compilation failed: internal java compiler error 解决方法: 1.打开菜单 ,File - Project Structure - Proj ...

  9. C#.NET Winform使用线程承载WCF (硬编码配置)

    winform同步承载WCF时,遇到大量请求,可能会阻塞UI线程.这时就需要开个线程来承载WCF. 1.硬编码形式创建WCF服务,WCFServer类: using CommonUtils; usin ...

  10. 重学前端 - react-第二节: 添加ts + scss

    重学前端 - react: 添加ts + scss 简介: 上一节我们新建了 react 项目.项目中并没有使用 ts + scss. 现在我们为项目添加 ts + scss.是项目后期维护更加方便, ...