热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

MySQLSQL优化案例:JOIN派生表

优化之前:SELECTap.institution_id,date(ra.create_time)date,sum(IF(ra.confirm_amount>
优化之前:
SELECT
ap.institution_id,
date(ra.create_time) date,
sum(

IF (
ra.confirm_amount > ld.debit_amount,
ld.debit_amount,
ra.confirm_amount
)
) return_amount,
count(ra.confirm_amount) return_count
FROM
t_asset_package ap
JOIN (
SELECT
asset_package_id,
institution_id,
loan_document_id,
debit_amount
FROM
t_loan_details
WHERE
is_all_paid = 1
OR principal_paid = 1
) ld ON ap.asset_package_id = ld.asset_package_id
JOIN (
SELECT
loan_document_id,
sum(confirm_amount) confirm_amount,
create_time
FROM
t_return_application
GROUP BY
loan_document_id
) ra ON ld.loan_document_id = ra.loan_document_id
WHERE
ap.institution_id = 'C0000012413'
AND ap.delete_flag = 0
GROUP BY
date(ra.create_time)
ORDER BY
date;

执行计划:

+----+-------------+----------------------+--------+-----------------------------------------+--------------------------------------+---------+---------------------+--------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------------------+--------+-----------------------------------------+--------------------------------------+---------+---------------------+--------+---------------------------------+
| 1 | PRIMARY | | ALL | NULL | NULL | NULL | NULL | 89435 | Using temporary; Using filesort |
| 1 | PRIMARY | | ALL | NULL | NULL | NULL | NULL | 88516 | Using where; Using join buffer |
| 1 | PRIMARY | ap | eq_ref | PRIMARY,FK_ASSET_PACKAGE_CUSTOMER_1_idx | PRIMARY | 110 | ld.asset_package_id | 1 | Using where |
| 3 | DERIVED | t_return_application | index | NULL | FK_RETURN_APPLICATION_DOCUMENT_1_idx | 111 | NULL | 203837 | |
| 2 | DERIVED | t_loan_details | ALL | NULL | NULL | NULL | NULL | 99370 | Using where |
+----+-------------+----------------------+--------+-----------------------------------------+--------------------------------------+---------+---------------------+--------+---------------------------------+
需要执行21分钟
优化思路:之前的SQL连接的是派生表,并不能有效使用到索引,导致这一写法的直接原因是程序员的惯性思维,总以为先把要join的内容通过过滤、分组、聚合限定在一个小的范围内之后再join效率较高且更符合惯常的思维模式。殊不知MySQL这么做会导致很差的性能。要做的优化就是先直接join这样可以利用到join字段上的索引,之后再进行过滤、分组 、聚合。
优化后:
SELECT
alr.institution_id,
alr.date,
SUM(

IF (
alr.confirm_amount > alr.debit_amount,
alr.debit_amount,
alr.confirm_amount
)
) return_amount,
count(alr.confirm_amount) return_count
FROM
(
SELECT
ap.institution_id institution_id,
DATE(ra.create_time) date,
SUM(ra.confirm_amount) confirm_amount,
ld.debit_amount debit_amount
FROM
t_asset_package ap
JOIN t_loan_details ld ON ap.asset_package_id = ld.asset_package_id
AND (
ld.is_all_paid = 1
OR ld.principal_paid = 1
)
JOIN t_return_application ra ON ld.loan_document_id = ra.loan_document_id
WHERE
ap.institution_id = 'C0000012413'
AND ap.delete_flag = 0
GROUP BY
ra.loan_document_id
) alr
GROUP BY
alr.date


执行计划:

+----+-------------+------------+------+-----------------------------------------------------------+-----------------------------------------+---------+------------------------------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+------+-----------------------------------------------------------+-----------------------------------------+---------+------------------------------+------+----------------------------------------------+
| 1 | PRIMARY | | ALL | NULL | NULL | NULL | NULL | 2 | Using temporary; Using filesort |
| 2 | DERIVED | ap | ref | PRIMARY,FK_ASSET_PACKAGE_CUSTOMER_1_idx | FK_ASSET_PACKAGE_CUSTOMER_1_idx | 63 | | 3 | Using where; Using temporary; Using filesort |
| 2 | DERIVED | ld | ref | IDX_LOAN_DOCUMENT,FK_LOAN_FEE_DETAILS_ASSET_PACKAGE_1_idx | FK_LOAN_FEE_DETAILS_ASSET_PACKAGE_1_idx | 111 | dcf_loan.ap.asset_package_id | 1 | Using where |
| 2 | DERIVED | ra | ref | FK_RETURN_APPLICATION_DOCUMENT_1_idx | FK_RETURN_APPLICATION_DOCUMENT_1_idx | 111 | dcf_loan.ld.loan_document_id | 1 | Using where |
+----+-------------+------------+------+-----------------------------------------------------------+-----------------------------------------+---------+------------------------------+------+----------------------------------------------+
只需运行0.01秒
推荐阅读
  • 合并列值-合并为一列问题需求:createtabletab(Aint,Bint,Cint)inserttabselect1,2,3unionallsel ... [详细]
  • 本文介绍了如何在MySQL中将零值替换为先前的非零值的方法,包括使用内联查询和更新查询。同时还提供了选择正确值的方法。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 本文介绍了在MySQL8.0中如何查看性能并解析SQL执行顺序。首先介绍了查询性能工具的开启方法,然后详细解析了SQL执行顺序中的每个步骤,包括from、on、join、where、group by、having、select distinct、union、order by和limit。同时还介绍了虚拟表的概念和生成过程。通过本文的解析,读者可以更好地理解MySQL8.0中的性能查看和SQL执行顺序。 ... [详细]
  • Windows7 64位系统安装PLSQL Developer的步骤和注意事项
    本文介绍了在Windows7 64位系统上安装PLSQL Developer的步骤和注意事项。首先下载并安装PLSQL Developer,注意不要安装在默认目录下。然后下载Windows 32位的oracle instant client,并解压到指定路径。最后,按照自己的喜好对解压后的文件进行命名和压缩。 ... [详细]
  • 本文介绍了OpenStack的逻辑概念以及其构成简介,包括了软件开源项目、基础设施资源管理平台、三大核心组件等内容。同时还介绍了Horizon(UI模块)等相关信息。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
author-avatar
娟儿2502923263
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有