MySQL的in查询效率太低的解决办法之一与其它优化示例

2023-10-12 20:10

本文主要是介绍MySQL的in查询效率太低的解决办法之一与其它优化示例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近在做一个MySQL数据库的查询(查询出指定时间之后凡是上传过图片的用户所在的镇和镇的管理员名),查询语句如下:

 

 SELECT DISTINCT user_name,town_name FROM t_farmers WHERE id IN 
(SELECT DISTINCT farmer_id FROM t_farmers_images WHERE create_time>='2017-07-05') 

 

其中farmers表有六千多记录,farmers_images表有近20万条记录,查询效率极低,此查询估计能够耗十分钟的时间,无法忍受,于是寻找解决办法,

网上有说加索引解决的,此处并未采取此方案,加索引或许确实能够解决问题,但时担心影响插入效率而且并非业务字段强相关故而暂未采取。

网上还有说把in改为exist,但是查询效率似乎并没有什么改变。通过搜阅资料得知in适合用于子表小的情况,而exist适合子表大主表小的情况,(仅代表一家之言,可能有不到之处,日后细究)。

 

解决方法如下:

上面的sql的执行计划如下:

可以看到为全表扫描,效率肯定会非常差;

经对数据库方面的文章参考,最终找到了一个方法,把in改为左连接右连接的方式命中索引,于是把sql语句改为如下:

 

 SELECT DISTINCT b.user_name,b.town_name FROM (SELECT DISTINCT farmer_id FROM t_farmers_images WHERE create_time>='2017-08-18') a
LEFT JOIN t_farmers b ON a.farmer_id=b.id 

查询效率瞬间提升,几乎感觉不到有什么延迟。

执行计划为:

可以看到命中b表的索引;

 

详细的左连接,右连接,内连接等的查询和哪种适合左边表大,哪种适合右边表大,哪种查询具体适合什么情形,请自行网上查询。

 

 

 

查询2月1号之后,总数之和超过300的用户:

SELECT mm.*,c.user_name,c.town_name,c.name,c.tel,c.card_id,c.onecard_id FROM (
SELECT a.farmer_id,SUM(death_number) FROM t_farmers_details a
WHERE a.date_time>='2017-02-01' GROUP BY a.farmer_id HAVING SUM(death_number)>=300 ) mm
LEFT JOIN t_farmers c ON c.id=mm.farmer_id

 

 

 

此外做项目时有经常需要用到多表查询的情况,全表扫描查询太慢,到现在才明白为什么两年前别人的项目中都用左连接,右连接之类的索引优先查询了,N多年后才明白别人当初的业务逻辑,还需要加把劲更加努力进步!

 

 

 

 

2017.12.07需要对已有系统进行优化,其中有一个导出Excel的功能,用户量小的时候导出功能正常,但是用户量大的时候导出特别慢,甚至网络差的时候还会出现导出失败的情况,起初以为是前端导出Excel效率低下的原因,后来经测试发现是数据库查询效率太差,

最初sql语句写法为:

SELECT a.*,(SELECT SUM(death_number) death_number FROM t_farmers_details 
WHERE date_time LIKE '%2017-12%' 
AND farmer_id =a.id ) harmless_quantity 
FROM t_farmers a WHERE 1=1 

执行计划为:

同样是全表扫描;

 

优化后sql语句写法为:

SELECT a.*,b.harmless_quantity 
FROM t_farmers a LEFT JOIN 
(SELECT b.farmer_id,SUM(b.death_number) harmless_quantity FROM t_farmers_details b 
WHERE b.date_time LIKE '%2017-12%' GROUP BY b.farmer_id ) b ON a.id=b.farmer_id 
WHERE 1=1 

执行计划为:

 

核心修改是多了temporary、filesort,

这样一来原来需要几分钟导出的一个Excel,现在只需几秒钟解决,特此记录。

初窥门径,不当之处还望指教。

 

 

 

欢迎大家进企鹅群交流:589847567;

 

这篇关于MySQL的in查询效率太低的解决办法之一与其它优化示例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/198172

相关文章

Linux搭建单机MySQL8.0.26版本的操作方法

《Linux搭建单机MySQL8.0.26版本的操作方法》:本文主要介绍Linux搭建单机MySQL8.0.26版本的操作方法,本文通过图文并茂的形式给大家讲解的非常详细,感兴趣的朋友一起看看吧... 目录概述环境信息数据库服务安装步骤下载前置依赖服务下载方式一:进入官网下载,并上传到宿主机中,适合离线环境

MySQL主从同步延迟问题的全面解决方案

《MySQL主从同步延迟问题的全面解决方案》MySQL主从同步延迟是分布式数据库系统中的常见问题,会导致从库读取到过期数据,影响业务一致性,下面我将深入分析延迟原因并提供多层次的解决方案,需要的朋友可... 目录一、同步延迟原因深度分析1.1 主从复制原理回顾1.2 延迟产生的关键环节二、实时监控与诊断方案

慢sql提前分析预警和动态sql替换-Mybatis-SQL

《慢sql提前分析预警和动态sql替换-Mybatis-SQL》为防止慢SQL问题而开发的MyBatis组件,该组件能够在开发、测试阶段自动分析SQL语句,并在出现慢SQL问题时通过Ducc配置实现动... 目录背景解决思路开源方案调研设计方案详细设计使用方法1、引入依赖jar包2、配置组件XML3、核心配

MySQL数据库约束深入详解

《MySQL数据库约束深入详解》:本文主要介绍MySQL数据库约束,在MySQL数据库中,约束是用来限制进入表中的数据类型的一种技术,通过使用约束,可以确保数据的准确性、完整性和可靠性,需要的朋友... 目录一、数据库约束的概念二、约束类型三、NOT NULL 非空约束四、DEFAULT 默认值约束五、UN

MySQL 多表连接操作方法(INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN)

《MySQL多表连接操作方法(INNERJOIN、LEFTJOIN、RIGHTJOIN、FULLOUTERJOIN)》多表连接是一种将两个或多个表中的数据组合在一起的SQL操作,通过连接,... 目录一、 什么是多表连接?二、 mysql 支持的连接类型三、 多表连接的语法四、实战示例 数据准备五、连接的性

MySQL中的分组和多表连接详解

《MySQL中的分组和多表连接详解》:本文主要介绍MySQL中的分组和多表连接的相关操作,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录mysql中的分组和多表连接一、MySQL的分组(group javascriptby )二、多表连接(表连接会产生大量的数据垃圾)MySQL中的

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

MyBatis模糊查询报错:ParserException: not supported.pos 问题解决

《MyBatis模糊查询报错:ParserException:notsupported.pos问题解决》本文主要介绍了MyBatis模糊查询报错:ParserException:notsuppo... 目录问题描述问题根源错误SQL解析逻辑深层原因分析三种解决方案方案一:使用CONCAT函数(推荐)方案二:

Python中的Walrus运算符分析示例详解

《Python中的Walrus运算符分析示例详解》Python中的Walrus运算符(:=)是Python3.8引入的一个新特性,允许在表达式中同时赋值和返回值,它的核心作用是减少重复计算,提升代码简... 目录1. 在循环中避免重复计算2. 在条件判断中同时赋值变量3. 在列表推导式或字典推导式中简化逻辑

Python位移操作和位运算的实现示例

《Python位移操作和位运算的实现示例》本文主要介绍了Python位移操作和位运算的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 位移操作1.1 左移操作 (<<)1.2 右移操作 (>>)注意事项:2. 位运算2.1