首页 > 其他分享 >使用order by id引发的慢查询

使用order by id引发的慢查询

时间:2023-03-02 15:35:51浏览次数:43  
标签:name 查询 索引 file order id select

背景

生产数据表达到900万条数据时有句sql出现全表扫描的情况,功能是模糊搜索file_name字段后使用id排序,sql如下,其中file_name字段有索引

select * from data_file   where file_name like 'hz_inspvatb_036%' order by id

问题分析

理想状态下这句sql应该使用file_name的索引,然后进行排序,实际对比发现不加order by id后走了索引,
加上id排序后使用了全表扫描,问题定位到order by id这里。
百度后解释如下:

你要知道innodb的普通索引块是会把主键值存进去的,当sql语句里面所有的字段都是索引字段(包括主键)时,mysql就可以只扫描索引就获取到需要的值,这时候就是索引覆盖扫描,而一旦你需要查询或者过滤其他的字段,mysql就需要回表扫描,这时候肯定是没有只扫描这个索引快了。一旦mysql发现你需要回表扫描的话,尤其还需要按照主键排序,那mysql就可能认为走主键更快就去走了主键扫描(实际上反而更慢)

所以就是由于MYSQL误判了查询方案,才导致的全表扫描,

解决方案

  1. 最优方案,把order by id 改为order by create_time,使用id排序的目的是为了按照创建时间倒序,因此可以使用create_time字段替换
select * from data_file   where file_name like 'hz_inspvatb_036%' order by create_time

测试结果: 时间从10s+变为180ms
2. 使用force index 强制使用指定索引

select df.id,df.file_name from data_file df force index(file_name_index) where file_name like 'hz_ins%' order by df.id

测试结果: 时间从10s+变为180ms
3. 慢回表方案

先用like查询出结果集的id,然后将这些id和原表联表取出所需字段,并通过id排序

select df2.file_name,df2.id,df2.file_path  from (select df.id as id from data_file df  where file_name like 'hz_inspvatb_036%') res
join data_file df2 
on df2.id = res.id
order by df2.id

测试结果: 时间从10s+变为240ms

案例二SQL

select d.file_name ,d.id as id
from data_file d left join permission p on d.permission_group_id = p.permission_group_id
where  d.file_name LIKE CONCAT('20220618_20220618_134206_069.avi','%')  AND
   (d.create_by_id  = 80040319 or ( (p.employee_id = 80040319 or p.department_id = 54 ) and p.has_query=1))
group by d.id ORDER BY id;

同样发现去除order by id 后走了索引,速度从12s 提升到40ms

优化后sql

select d.file_name ,d.id as id,d.create_time as create_time
from data_file d left join permission p on d.permission_group_id = p.permission_group_id
where  d.file_name LIKE CONCAT('20220618_20220618_134206_069.avi','%')  AND
    (d.create_by_id  = 80040319 or ( (p.employee_id = 80040319 or p.department_id = 54 ) and p.has_query=1))
group by d.id ORDER BY crete_time;

标签:name,查询,索引,file,order,id,select
From: https://www.cnblogs.com/rise0111/p/17171913.html

相关文章

  • 什么是Bundle ID​
    登录成功后我们可以看到弹出的消息提示“您账号未支付688给apple,只能创建开发证书,无法提交上传发布,无法使用apple登录,支付,推送功能”,简单来说就是只能使用此款软件进行内测,......
  • Fiddler 对真机(Android 系统)上 App 抓包图文详解 (超全)
    作为测试或开发经常需要抓取手机App的HTTP/HTTPS的数据包,通过查看App发出的HTTP请求和响应数据来协助开发去修复bug。对于测试而言,通过抓包+分析,去定位bug的前后端归属问题......
  • 什么是Bundle ID​
    什么是BundleID​登录成功后我们可以看到弹出的消息提示“您账号未支付688给apple,只能创建开发证书,无法提交上传发布,无法使用apple登录,支付,推送功能”,简单来说就是只能使......
  • 使用 SQL 中的递归查询(Recursive CTE)来实现1-50数字
    1.使用SQL中的递归查询(RecursiveCTE)来实现。以下是使用T-SQL语法的示例代码:WITHNumbersAS(SELECT1ASNumberUNIONALLSELECTNumber+1F......
  • 蒙特利尔大学提出强度图像-LiDAR SLAM,针对低纹理和非结构化环境!
    以下内容来自小六的机器人SLAM学习圈知识星球每日更新内容点击领取学习资料→机器人SLAM学习资料大礼包论文#Real-TimeSimultaneousLocalizationandMappingwith......
  • Jquery EasyUI datagrid分页
    <!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN"><html><head></head><body><tableid="people_datagrid"></table></body></html> //显示人员......
  • Android自定义view实现加载中、加载失败、无数据
    一、概述Android中经常在有的app中可以见到“加载中”并不是以弹出对话框的形式显示的,而是占用整个屏幕,如果加载失败就会出现加载失败页面,点击加载失败页面中任意区域,都可以......
  • Android面试题汇总
    1.面试题:知道Service吗,它有几种启动方式?Service是一个专门在后台处理长时间任务的Android组件,它没有UI。它有两种启动方式,startService和bindService。startService只是......
  • Android图像处理实例解析
    一、概述本篇文章介绍的是关于Android图像处理相关的,主要有动态修改图像的色相、饱和度及亮度,颜色矩阵,图像像素点调整、图像矩阵实现图像的平移缩放等,Xfermode相关知识点,......
  • Android Studio 友盟api实现apk多渠道打包
    本篇主要给大家介绍利用友盟api实现Android多渠道打包,进入友盟的官网,注册账号,添加对应的应用。1.添加友盟库的依赖2.在manifest.xml中声明appkey,以及渠道占位符3.builde......