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到底 ...
随机推荐
- NOIP 2003 乒乓球
洛谷 P1042 乒乓球 https://www.luogu.org/problemnew/show/P1042 JDOJ 1363: [NOIP2003]乒乓球 T1 https://neooj.c ...
- LG3004 「USACO2010DEC」Treasure Chest 区间DP+滚动数组优化
问题描述 LG3004 题解 把拿走的过程反向,看做添加的过程,于是很显然的区间DP模型. 设\(opt_{i,j}\)代表区间\([i,j]\)中Bessie可以获得的最大值,显然有 \[opt_{ ...
- Leetcode142 环形链表
很多题解没有讲清楚非环部分的长度与相遇点到环起点那部分环之间为何是相等的这个数学关系.这里我就补充下为何他们是相等的.假设非环部分的长度是x,从环起点到相遇点的长度是y.环的长度是c.现在走的慢的那个 ...
- koa2中的ctx是什么?
为了试图搞明白,用console.log将它输出 const Koa = require('koa'); const app = new Koa(); app.use(ctx => { ctx. ...
- nwjs-简介
nwjs是基于nodejs的,它支持nodejs所有的api,主要用于跨平台轻量级桌面应用开发,运行环境包括32位和64位的Window.Linux和Mac OS nwjs是在英特尔开源技术中心创建的 ...
- map、set 使用方法 | 1022 图书馆信息查询
看了答案才知道了这题的各种骚操作,然后敲了一顿骚键盘,然后wa.调了很久,才发现要规格化打印……mdzz…… 注:加粗代码为傻逼规格化打印代码: #include <stdio.h> #i ...
- windows下sed回车换行符处理
windows下sed回车换行符处理如果用sed for windows对整个文件进行了编辑,编辑之后一般需要处理回车换行符:rem windows的回车换行符是\r\n,linux的是\n,所以要替 ...
- Linux性能优化实战学习笔记:第五十讲
一.上节回顾 上一节,我以 ksoftirqd CPU 使用率高的问题为例,带你一起学习了内核线程 CPU 使用率高时的分析方法.先简单回顾一下. 当碰到内核线程的资源使用异常时,很多常用的进程级性能 ...
- [LeetCode] 464. Can I Win 我能赢吗
In the "100 game," two players take turns adding, to a running total, any integer from 1.. ...
- [LeetCode] 350. Intersection of Two Arrays II 两个数组相交之二
Given two arrays, write a function to compute their intersection. Example 1: Input: nums1 = [1,2,2,1 ...