MySQL查询优化一例——也说说 Using intersect
生产上面有一条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;
执行计划如下所示:

可以看到 执行计划里面出现了 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')
执行计划如下:

比较一下前面和后面两个的执行计划,可以发现 都是有了 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秒相比,还是有差距。执行计划如下;

可以看到没有了 Using interset. 我们强制使用索引 btjc01048.
总结:
如果出现 Using interset 需要注意是否mysql优化器选择的是否是最佳的索引方案。是否可以通过force index来选择更优的索引。
MySQL查询优化一例——也说说 Using intersect的更多相关文章
- MySQL查询优化(转)
在分析性能欠佳的查询时,应考虑: 1) 应用程序是否正获取超过需要的数据,即访问了过多的行或列. 2) Mysql服务器是否分析了超过需要的行. 如果发现访问的数据行数很大,而生成的结果中数据行很少, ...
- MySQL 查询优化之 Index Merge
MySQL 查询优化之 Index Merge Index Merge Intersection 访问算法 Index Merge Union 访问算法 Index Merge Sort-Union ...
- Mysql查询优化汇总 order by优化例子,group by优化例子,limit优化例子,优化建议
Mysql查询优化汇总 order by优化例子,group by优化例子,limit优化例子,优化建议 索引 索引是一种存储引擎快速查询记录的一种数据结构. 注意 MYSQL一次查询只能使用一个索引 ...
- Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析
Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析 Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析1 存 ...
- MySQL查询优化之explain的深入解析
在分析查询性能时,考虑EXPLAIN关键字同样很管用.EXPLAIN关键字一般放在SELECT查询语句的前面,用于描述MySQL如何执行查询操作.以及MySQL成功返回结果集需要执行的行数.expla ...
- 1025WHERE执行顺序以及MySQL查询优化器
转自http://blog.csdn.net/zhanyan_x/article/details/25294539 -- WHERE执行顺序-- 过滤比较多的放在前面,然后更加容易匹配,从左到右进行执 ...
- MySQL查询优化:查询慢原因和解决技巧
在开发的朋友特别是和mysql有接触的朋友会碰到有时mysql查询很慢,当然我指的是大数据量百万千万级了,不是几十条了,下面我们来看看解决查询慢的办法. MySQL查询优化:查询慢原因和解决方法 会经 ...
- mysql查询优化器为什么可能会选择错误的执行计划
有可能导致mysql优化器选择错误的执行计划的原因如下: A:统计信息不准确,mysql依赖存储引擎为其提供的统计信息来评估成本,然而有的存储引擎提供的信息是准确的,有的引擎提供的可能就偏差很大,如: ...
- Mysql查询优化器
Mysql查询优化器 本文的目的主要是通过告诉大家,查询优化器为我们做了那些工作,我们怎么做,才能使查询优化器对我们的sql进行优化,以及启示我们sql语句怎么写,才能更有效率.那么到底mysql到底 ...
随机推荐
- Git 创建点开头的文件和目录
Git 创建点开头的文件和目录 # 创建 .gitignore 文件 1@DESKTOP-3H9092J MINGW64 /e/x1/x1/demo1 (master) $ echo .idea &g ...
- About me & 友链
窝是图图小淘气 面对世界很好奇 啊呸 抱歉 拿错咧 重来 是他!是他!就是他! 我们滴朋友哦小哪吒! (汗 又拿错咧 菜鸡yxj 是来自美丽富饶的SDGR 的一名高中生 每天最喜欢做的事就是 花式被机 ...
- 洛谷 P1209 [USACO1.3]修理牛棚 Barn Repair题解
题目 打死我也没想到是贪心 虽然是lkx写了贪心题解让我去点赞我才写的这道题 神仙思路 首先排好序 假设我们现在只有一块木板 我们做一个差分数组 对这个差分数组排序之后 一次断开最长的区间 m-1次之 ...
- 学习vue_01
目录 vue 框架: 框架介绍 基础格式 插值表达式: 文本指令: 事件指令: 属性指令: 小结: js 补充(面向对象): vue 框架: --构建虚拟的DOM结构,(内存内改变对象)- 操作数据的 ...
- NOI 2019 退役记
非常抱歉,因为不退役了,所以这篇退役记鸽了.
- Javascript 笔记:原型和原型链
一.函数对象和普通对象 凡是通过new Function()创建的都是函数对象,其它的都是普通对象.Function,Object,Array,Number,String,Boolean,Date是J ...
- .NET Core:Token认证
现在是WebAPI的时代,你所需要面对的不止是浏览器了,通常会使用Web, WebApp, NativeApp等多种呈现方式.其中诸如Ember,Angular,Backbone之类的前端框架类库正随 ...
- 浏览器console中加入jquery方便调试
var jquery = document.createElement('script'); jquery.src = "http://apps.bdimg.com/libs/jquery/ ...
- Qt Quick 多媒体 - 播放音乐和视频
MediaPlayer 是 QML 提供的核心多媒体类,可以播放音频.视频.要使用 MediaPlayer,需要引入 QtMultimedia 模块,在 QML 文档的开始加入 "impor ...
- SpringBoot第四篇:整合JDBCTemplate
作者:追梦1819 原文:https://www.cnblogs.com/yanfei1819/p/10868954.html 版权声明:本文为博主原创文章,转载请附上博文链接! 引言 前面几篇文 ...