MySQL查询优化一例——也说说 Using intersect

摘要:
=inibeginmonthUNIONALLSELECTbtjc01.id,部门.`name`ASbtjc01011,btjc01011ASobj,btjc01.beginYearMonth,btjc01,btjc01030,CASEWHENbtjc01。inibeginmonth='2019-10'THEN'是'ELSE'否'ENDASIsadFROMbtjc01INNEJOINDepartmentONdepartment。Id=btjc01.btjc01038INNERJOINbtgg03ONbtgg03。Id=btjc01.btjc01040WHERE btjc01。btjc01037='3'ANDbtjc01046='江西省'ANDbtjc01047='九江市'ANDbtjc01048='修水县'AND实施计划如下:比较前两个实施计划和后两个实施方案,可以发现它们都有Usingintersect,但后一个仅需0.4秒,而在外部添加一层select*需要7到8秒。我不明白为什么。最后的优化是删除Usinginterset,使用forceindex手动指定使用索引btjc01048:SELECTmingxi。*自(SELECTbtjc01。id,部门。`名称`ASbtjc01011,btjc01011ASobj,btjc01。开始月份开始年份月份,lsbtsj。btjeASbtjc01030,CASEWHENbtjc01。inibeginmonth='2019-10'THEN'Yes'ELSE'No'ENDASIsadFROMbtjc01forceindex(btjc01048)INNERJOINdepartmentONdepartment。Id=btjc01.btjc01038 INNERJOINlsbtsjONlsbtsj。btrid=btjc01.IdWHERE btjc01。btjc01037='3'和btjc01046=“江西省”ANDbtjc01047=“九江市”ANDbtjc01048=“修水县”ANDlsbtsj。btqsyf='2019-10'和第二个月!

生产上面有一条sql查询很慢,需要7到8秒左右,简化之后的sql如下所示:

SELECT
	mingxi.*
FROM
	(
		SELECT
			btjc01.id,			
			department.`name` AS btjc01011,
			btjc01011 AS obj,
			btjc01.inibeginmonth AS beginYearMonth,
			lsbtsj.btje AS btjc01030,			
						
			CASE
		WHEN btjc01.inibeginmonth ='2019-10' THEN
			'是'
		ELSE
			'否'
		END AS isadd
		FROM
			btjc01
		INNER JOIN department ON department.Id = btjc01.btjc01038
		INNER JOIN lsbtsj ON lsbtsj.btrid = btjc01.Id
		WHERE
			btjc01.btjc01037 = '3'
		AND btjc01046 ='江西省'
		AND btjc01047 ='九江市'
		AND btjc01048 ='修水县'		
		AND lsbtsj.btqsyf <='2019-10'
		AND lsbtsj.btjzyf >='2019-10'
		AND beginYearMonth != inibeginmonth
		UNION ALL
			SELECT
				btjc01.id,
						
				department.`name` AS btjc01011,
				btjc01011 AS obj,
				btjc01.beginYearMonth,
				btjc01.btjc01030,				
				
				CASE
			WHEN btjc01.inibeginmonth ='2019-10' THEN
				'是'
			ELSE
				'否'
			END AS isadd
			FROM
				btjc01 
			INNER JOIN department ON department.Id = btjc01.btjc01038
			INNER JOIN btgg03 ON btgg03.Id = btjc01.btjc01040
			WHERE
				btjc01.btjc01037 = '3'
		AND btjc01046 ='江西省'
		AND btjc01047 ='九江市'
		AND btjc01048 ='修水县'
		AND (beginYearMonth <='2019-10')
	) AS mingxi

LIMIT 100,200;

执行计划如下所示:

MySQL查询优化一例——也说说 Using intersect第1张

  可以看到 执行计划里面出现了 Using intersect,btjc01046 btjc01048 btjc01037 btjc01047 多个索引来进行数据的过滤。

另外发现一个问题,里面的 union all 子查询 却只需要 0.4秒就可以执行完成:

SELECT
			btjc01.id,			
			department.`name` AS btjc01011,
			btjc01011 AS obj,
			btjc01.inibeginmonth AS beginYearMonth,
			lsbtsj.btje AS btjc01030,			
						
			CASE
		WHEN btjc01.inibeginmonth ='2019-10' THEN
			'是'
		ELSE
			'否'
		END AS isadd
		FROM
			btjc01
		INNER JOIN department ON department.Id = btjc01.btjc01038
		INNER JOIN lsbtsj ON lsbtsj.btrid = btjc01.Id
		WHERE
			btjc01.btjc01037 = '3'
		AND btjc01046 ='江西省'
		AND btjc01047 ='九江市'
		AND btjc01048 ='修水县'		
		AND lsbtsj.btqsyf <='2019-10'
		AND lsbtsj.btjzyf >='2019-10'
		AND beginYearMonth != inibeginmonth
		UNION ALL
			SELECT
				btjc01.id,
						
				department.`name` AS btjc01011,
				btjc01011 AS obj,
				btjc01.beginYearMonth,
				btjc01.btjc01030,				
				
				CASE
			WHEN btjc01.inibeginmonth ='2019-10' THEN
				'是'
			ELSE
				'否'
			END AS isadd
			FROM
				btjc01 
			INNER JOIN department ON department.Id = btjc01.btjc01038
			INNER JOIN btgg03 ON btgg03.Id = btjc01.btjc01040
			WHERE
				btjc01.btjc01037 = '3'
		AND btjc01046 ='江西省'
		AND btjc01047 ='九江市'
		AND btjc01048 ='修水县'
		AND (beginYearMonth <='2019-10')  

执行计划如下:

MySQL查询优化一例——也说说 Using intersect第2张

 比较一下前面和后面两个的执行计划,可以发现 都是有了 Using intersect 但是呢后面一个却只需要0.4秒,而在外面加上一层 select * from t,时间却需要7到8秒。一直没有明白什么原因。

最后的优化是去掉 Using interset ,使用 force index 手动指定使用索引 btjc01048:

SELECT
	mingxi.*
FROM
	(
		SELECT
			btjc01.id,			
			department.`name` AS btjc01011,
			btjc01011 AS obj,
			btjc01.inibeginmonth AS beginYearMonth,
			lsbtsj.btje AS btjc01030,			
						
			CASE
		WHEN btjc01.inibeginmonth ='2019-10' THEN
			'是'
		ELSE
			'否'
		END AS isadd
		FROM
			btjc01 force index(btjc01048)
		INNER JOIN department ON department.Id = btjc01.btjc01038
		INNER JOIN lsbtsj ON lsbtsj.btrid = btjc01.Id
		WHERE
			btjc01.btjc01037 = '3'
		AND btjc01046 ='江西省'
		AND btjc01047 ='九江市'
		AND btjc01048 ='修水县'		
		AND lsbtsj.btqsyf <='2019-10'
		AND lsbtsj.btjzyf >='2019-10'
		AND beginYearMonth != inibeginmonth
		UNION ALL
			SELECT
				btjc01.id,
						
				department.`name` AS btjc01011,
				btjc01011 AS obj,
				btjc01.beginYearMonth,
				btjc01.btjc01030,				
				
				CASE
			WHEN btjc01.inibeginmonth ='2019-10' THEN
				'是'
			ELSE
				'否'
			END AS isadd
			FROM
				btjc01 force index(btjc01048)
			INNER JOIN department ON department.Id = btjc01.btjc01038
			INNER JOIN btgg03 ON btgg03.Id = btjc01.btjc01040
			WHERE
				btjc01.btjc01037 = '3'
		AND btjc01046 ='江西省'
		AND btjc01047 ='九江市'
		AND btjc01048 ='修水县'
		AND (beginYearMonth <='2019-10')
	) AS mingxi

LIMIT 100,200;

  执行时间需要1.2秒左右,和0.4秒相比,还是有差距。执行计划如下;

MySQL查询优化一例——也说说 Using intersect第3张

 可以看到没有了 Using interset. 我们强制使用索引 btjc01048.

总结:

如果出现 Using interset 需要注意是否mysql优化器选择的是否是最佳的索引方案。是否可以通过force index来选择更优的索引。

免责声明:文章转载自《MySQL查询优化一例——也说说 Using intersect》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇TreeView和TabControlMATLAB的基本元素下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

mycat的下载和安装

MySQL安装与启动 JDK:要求jdk必须是1.7及以上版本 MySQL:推荐mysql是5.5以上版本 MySQL安装与启动步骤如下:( 步骤1-5省略 ) (1)将MySQL的服务端和客户端安装包(RPM)上传到服务器   (2)查询之前是否安装过MySQL ? 1 rpm -qa|grep-i mysql (3)卸载旧版本MySQL...

青蛙学Linux—MySQL安装和初始化

1、安装MySQL 这里我们选择MySQL的源码包进行安装,MySQL版本5.7,安装路径为/usr/local/mysql,数据存储路径为/db/mysql,日志文件路径/usr/local/mysql/logs,运行MySQL的用户和组为mysql。 1.1、创建mysql用户 mysql用户用于运行MySQL,不能使用shell,为虚拟用户: [ro...

mysql索引无效且sending data耗时巨大原因分析

一朋友最近新上线一个项目,本地测试环境跑得好好的,部署到线上却慢得像蜗牛一样。后来查询了一下发现一个sql执行了16秒,有些长的甚至80秒。本地运行都是毫秒级别的查询。下面记录一下困扰了两天的,其中一条sql的优化。 表结构及现象描述: CREATE TABLE`wp_goods` ( `id` bigint(20) unsigned NOT NUL...

编写SQL需要注意的细节 Checklist总结

本周技术研究部(TRD)的一名DBA 对我们编写SQL时的一些问题,进行了汇报讲演,以下是来自它的脚本,我在它讲演的基础上写出了自己想表述的,以便于大家相互交流学习。 /*--注意:准备数据(可略过,非常耗时) CREATE TABLE CHECK1_T1 ( ID INT, C1 CHAR(8000) ) CREATE TABLE CH...

MySQL 同时 delete 多张表的数据

三张表 article ,tag,article_tag article 文章表 create tablearticle( article_id int primary keyauto_increment, article_title varchar(100) ); insert into article(article_title) va...

【等待优化】SQL SERVER常见等待——解决会话等待产生的系统问题

SQL SERVER——解决会话等待产生的系统问题 转自:https://blog.csdn.net/z_cloud_for_SQL/article/details/55051215 版权声明:SQL专家云- 国内唯一的SQL Server体检、诊断、监控一体化平台 注册用户即可永久免费使用 https://blog.csdn.net/z_clo...