生产上面有一条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的更多相关文章

  1. MySQL查询优化(转)

    在分析性能欠佳的查询时,应考虑: 1) 应用程序是否正获取超过需要的数据,即访问了过多的行或列. 2) Mysql服务器是否分析了超过需要的行. 如果发现访问的数据行数很大,而生成的结果中数据行很少, ...

  2. MySQL 查询优化之 Index Merge

    MySQL 查询优化之 Index Merge Index Merge Intersection 访问算法 Index Merge Union 访问算法 Index Merge Sort-Union ...

  3. Mysql查询优化汇总 order by优化例子,group by优化例子,limit优化例子,优化建议

    Mysql查询优化汇总 order by优化例子,group by优化例子,limit优化例子,优化建议 索引 索引是一种存储引擎快速查询记录的一种数据结构. 注意 MYSQL一次查询只能使用一个索引 ...

  4. Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析

    Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析     Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析1 存 ...

  5. MySQL查询优化之explain的深入解析

    在分析查询性能时,考虑EXPLAIN关键字同样很管用.EXPLAIN关键字一般放在SELECT查询语句的前面,用于描述MySQL如何执行查询操作.以及MySQL成功返回结果集需要执行的行数.expla ...

  6. 1025WHERE执行顺序以及MySQL查询优化器

    转自http://blog.csdn.net/zhanyan_x/article/details/25294539 -- WHERE执行顺序-- 过滤比较多的放在前面,然后更加容易匹配,从左到右进行执 ...

  7. MySQL查询优化:查询慢原因和解决技巧

    在开发的朋友特别是和mysql有接触的朋友会碰到有时mysql查询很慢,当然我指的是大数据量百万千万级了,不是几十条了,下面我们来看看解决查询慢的办法. MySQL查询优化:查询慢原因和解决方法 会经 ...

  8. mysql查询优化器为什么可能会选择错误的执行计划

    有可能导致mysql优化器选择错误的执行计划的原因如下: A:统计信息不准确,mysql依赖存储引擎为其提供的统计信息来评估成本,然而有的存储引擎提供的信息是准确的,有的引擎提供的可能就偏差很大,如: ...

  9. Mysql查询优化器

    Mysql查询优化器 本文的目的主要是通过告诉大家,查询优化器为我们做了那些工作,我们怎么做,才能使查询优化器对我们的sql进行优化,以及启示我们sql语句怎么写,才能更有效率.那么到底mysql到底 ...

随机推荐

  1. Azure产品整理

    Azure的文档真是够落地,简明易懂. 计算 Linux 虚拟机:为 Ubuntu.Red Hat 等预配虚拟机 Windows 虚拟机 为 SQL Server.SharePoint 等预配虚拟机 ...

  2. webapi基于单请求封装多请求的设计【转】

    怎么说,单请求封装多请求,这句话确实有点绕了,但还是要看清楚,想明白这到底是怎么一回事,单请求即一次请求(get,post,put,delete),封闭多请求,即在客户端发送的一个请求中可能包含多个子 ...

  3. [LeetCode] 51. N-Queens N皇后问题

    The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens ...

  4. ES方法使用注意

    matchQuery:会将搜索词分词,再与目标查询字段进行匹配,若分词中的任意一个词与目标字段匹配上,则可查询到.   termQuery:不会对搜索词进行分词处理,而是作为一个整体与目标字段进行匹配 ...

  5. Linux系统运维笔记,CentOS 7.4防火墙配置

    1.查看firewall服务状态 systemctl status firewalld 2.查看firewall的状态 firewall-cmd --state 3.开启.重启.关闭.firewall ...

  6. oracle--DBWN

    一,DBWN功能 将脏数据写盘 二,什么情况下会触发DBWN的进程呢? 1) check pointer:有检查点, 2) 脏数据达到阀值:达到buffer内存的10%即要将脏数据写到磁盘: 这就是造 ...

  7. C# HTTP系列2 HttpWebReponse类

    系列目录     [已更新最新开发文章,点击查看详细] System.Net.HttpWebReponse 类提供 WebResponse 类的特定于HTTP的实现. 例子 下面的示例返回一个从Htt ...

  8. prometheus consul docker redis_exporter 自动注册配置

    0.启动redis_exporter redis_exporter: version: '2'services: redis_exporter: image: oliver006/redis_expo ...

  9. 改写URL的查询字符串QUERY_STRING[URL重定向问号问题](转)

    查询字符串是指URL请求中"问号"后面的部分.比如,http://mysite/?foo=bar 中粗体部分就是查询字符串,其中变量名是foo,值是bar. 'last|L' (最 ...

  10. Hbase Filter之PrefixFilter

    PrefixFilter PrefixFilter是将rowkey前缀为指定字符串的数据全部过滤出来并返回给用户.例如: Scan scan = new Scan(); scan.setFilter( ...