前情引子

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静态变量在静态方法内部无法改变值

    一.如何解决"Java静态变量在静态方法内部无法改变值"的问题 在Java中,静态变量(也称为类变量)属于类本身,而不是类的任何特定实例.它们可以在没有创建类的实例的情况下访问和修 ...

  2. .net Mvc5Webapi接口接收参数为null的一种情况分享

    同样的前后端项目,其他接口用post接收自定义对象形式的参数,是能成功接收的.在这个前提下,出现某个接口接收的参数为null或值全是默认值,可能的原因是这样: 前端定义的参数的字段比后台定义的dto对 ...

  3. yapi 自动化安装遇到的问题

    yapi版本: 1.10.2 yapi server 启动之后 填写好配置,点击开始部署,发现控制台打印如下日志 (node:19879) Warning: Accessing non-existen ...

  4. 用 vue2 和 webpack 快速建构 NW.js 项目

    经过实践和学习,发现本篇文章部分内容已经过时,请看我的关于 Vue 和 NW.js 的 ** 最新文章 ** 和相关实践项目 vue-nw-seed . 使用到的技能点 vue2 webpack NW ...

  5. mescroll.js 使用

    mescroll.js 使用 附:点击查看中文文档 第一步:引入css和js // unpkg的CDN: <link rel="stylesheet" href=" ...

  6. kettle从入门到精通 第二十八课 初识kettle-job

    1.前面我们一起学习了,很多转换的知识,转换为批量的开发做铺垫,今天我们一起来学习下kettle job的知识. kettle job 常用的步骤如下图,有Start.转换.作业.成功等步骤. 2.下 ...

  7. Mybatis-MySQL 中使用IFNUL

    Mybatis-MySQL 中使用IFNULL(p1,p2)函数但是有一些需要注意的地方. 假设数据 title: student id name age 1 Ann 18 2 Bom 19 3 He ...

  8. pyenv-win 替换国内镜像源

    前情提要 今天心血来潮想学一学python 然后因为python版本众多,了解到了pyenv这个python版本管理器 在github下载好pyenv以后,打算先安装一个稳定的版本 pyenv ins ...

  9. maven和gradle环境变量配置及idea相关的设置

    1.maven 环境变量添加之后,重新打开cmd窗口,验证是否配置成功. idea   File >> Settings idea配置之后的验证: 2.gradle 环境变量添加之后,重新 ...

  10. Excel Wps 透视表去重计数方法

    Excel Wps 透视表去重计数方法 在处理表格,遇到处理根据某个列去重后统计数量,而不是仅仅统计数量.在网上查找资料,不确定EXCEL或者WPS某个版本可以支持该功能的实现. 折中的方案,分两步来 ...