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到底 ...
随机推荐
- Leetcode.142-Linked-list-cycle-ii(环形链表II)
环形链表II 思路 https://www.cnblogs.com/springfor/p/3862125.html https://blog.csdn.net/u010292561/article/ ...
- 使用表格 代替 txt文件(未完结)
使用xlrd读取用户数据 首先创建一个xls文件 xlrd模块的简单使用 添加处理execl的接口: 使用excel生成测试报表
- STOMP 客户端 API 整理
STOMP(Simple Text-Orientated Messaging Protocol) 面向消息的简单文本协议WebSocket是一个消息架构,不强制使用任何特定的消息协议,它依赖于应用层解 ...
- Python爬虫练习
例一:爬取信息关于'gbk' codec can't encode character '\xa0' in position 6: illegal 错误提示: #初始化class 得到对象 draw= ...
- Asp.Net Core 减少Controller获取重复注入对象
原文:Asp.Net Core 减少Controller获取重复注入对象 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u012770274/art ...
- Debian/Ubuntu下安装Apache的Mod_Rewrite模块的步骤
启用 Mod_rewrite 模块:sudo a2enmod rewrite 另外,也可以通过将 /etc/apache2/mods-available/rewrite.load 连接到 /etc/a ...
- nginx 目录自动加斜线”/”
默认配置当你访问http://abc.example.com/dir 时不会加”/” 常见做法 if (-d $request_filename){ rewrite ^/(.*)([^/])$ ht ...
- go-gin-api 路由中间件 - 签名验证(七)
概览 首先同步下项目概况: 上篇文章分享了,路由中间件 - Jaeger 链路追踪(实战篇),文章反响真是出乎意料, 「Go中国」 公众号也转发了,有很多朋友加我好友交流,直呼我大神,其实我哪是什么大 ...
- Linux内核之vmlinuz反汇编
本文介绍在Fedora上对Linux内核的vmlinuz进行反汇编.如果内核是debug版本,可以用来查看某个函数的源代码. 1. 安装kernel-devel软件包 dnf -y install k ...
- 使用spring jpa hibernate框架时报错:javax.validation.UnexpectedTypeException: HV000030
错误信息: [#%&*^]20190521121942:497.!react:all.,RctJobExecutor-1#D9AA5167921A464CA9DDA14943545426%NA ...