首页 > 数据库 >MYSQL DQL in 到底会不会走索引&in 范围查询引发的思考。

MYSQL DQL in 到底会不会走索引&in 范围查询引发的思考。

时间:2024-07-16 23:08:37浏览次数:18  
标签:5w 使用 userId 分表 查询 索引 MYSQL DQL

前情引子

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操作进行了优化、但仍旧不能保证。

 

 

标签:5w,使用,userId,分表,查询,索引,MYSQL,DQL
From: https://www.cnblogs.com/richicewoo/p/18304194

相关文章

  • MySQL【表完整性约束】
    约束条件说明primarykey(PK)标识该字段为该表的主键,唯一性,不为空;UNIQUE+NOTNULLforeignkey(FK)标识该字段为该表的外键,实现表与表之间的关联null标识是否允许为空,默认为NULL。notnull标识该字段不能为空,可以修改。uniquekey(UK)标识该字段的值是唯一的......
  • MySQL【源码安装安装 mysql】
    1.当前目录:修改属主属组cd/usr/local/mysqlchown-Rmysql.mysql.2.初始化数据库:mysql/bin/mysqld./bin/mysqld--initialize--user=mysql--basedir=/usr/local/mysql--datadir=/usr/local/mysql/data/#拿到随机密码:#[Note]Atemporarypasswordisgeneratedf......
  • WPF read data from mysql and display via ADO.NET
    //xaml<Windowx:Class="WpfApp216.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.mi......
  • MySQL主从复制过程
    1、主库操作:修改数据库配置文件liunx的my.cnf文件;windows系统的my.ini文件[mysqld]#最大链接数max_connections=1000#主库----start---同一局域网内注意要唯一server-id=100#开启二进制日志功能,可以随便取(关键)log-bin=mysql-bin#记录的数据库(多数据库用逗号......
  • MySQL 索引
    MySQL索引一、介绍二、索引的分类三、单列索引、组合索引四、全文索引五、空间索引六、索引的原理、优缺点、创建原则一、介绍索引是通过某种算法,构建出一个数据模型,用于快速找出在某个列中有一特定值的行,不使用索引,MySQL必须从第一条记录开始读完整个表,直到找出相关的......
  • MySQL数据库一主一从集群配置
    环境环境三部曲1.全新服务器-互相通信2.全新安装mysql8.0-分别安装3.配置域名解析这里来讲一主一从的第二种连接方式,第一种的话可以参考下面连接:第一种方式一主一从(M-S)(2)需求实验2与上一个实验需求基本相同。master1作为主mysqlmaster2作为从mysql。不同之......
  • MySQL 数据库 day 7.16
        ok了家人们今天继续记录一下数据库,看看今天学了什么。一.事物概述1.1环境准备--账户表createtableaccount(idintprimarykeyauto_increment,namevarchar(20),moneydouble);insertintoaccountvalues(null,'张三',1000......
  • MySQL基础(必会)
    目录MySQL基础数据类型:事务事务操作事务的四大特性,ACID并发事务问题事务隔离级别MySQL基础数据类型:数值类型:字符类型:(!!!!char和varchar的区别一定要记住,博主第一次面试就被问到了)日期时间类型:事务事务是一系列操作的集合,他是不可分割的工作单位,事务会把所有的操作......
  • MySQL版本的相关问题:com.mysql.cj.jdbc.Driver和com.mysql.jdbc.Driver
    原文链接:https://www.cnblogs.com/daemonFlY/p/9820541.html1.在使用mysql时,控制台日志报错如下:Loadingclass`com.mysql.jdbc.Driver'.Thisisdeprecated.Thenewdriverclassis`com.mysql.cj.jdbc.Driver'.ThedriverisautomaticallyregisteredviatheSPIand......
  • 解读InnoDB数据库索引页与数据行的紧密关联
    目录一、快速走进索引页结构(一)整体展示说明(二)内容说明FileHeader(文件头部)PageHeader(页面头部)Infimum+Supremum(最小记录和最大记录)UserRecords(用户记录) FreeSpace(空闲空间)PageDirectory(页面目录)FileTrailer(文件尾部)二、索引页与记录行的简单关系说明(一)数据......