记一次生产sql优化

总结优化思路
1分析当前业务
2定位慢查询arthas
3分析查询参数,优化查询参数 ,优化返回结果
4explan 分析慢查询 根据sql 分解sql,看哪一个子查询慢,优化索引,优化查询顺序结构等
5以上都不行 前期就应该建立分库分表 或者使用ck nosql 进行查询

arthas 分析结果如下

[arthas@25356]$ trace com.rfca.dao.mapper.ParkingMapper QueryLatePhoto
Press Q or Ctrl+C to abort.
Affect(class count: 2 , method count: 1) cost in 140 ms, listenerId: 13
`---ts=2022-05-19 13:09:39;thread_name=pool-4-thread-6;id=67;is_daemon=false;priority=5;TCCL=org.apache.catalina.loader.ParallelWebappClassLoader@62cc7715
    `---[28.034673ms] com.sun.proxy.$Proxy120:QueryLatePhoto()

`---ts=2022-05-19 13:09:50;thread_name=pool-4-thread-4;id=65;is_daemon=false;priority=5;TCCL=org.apache.catalina.loader.ParallelWebappClassLoader@62cc7715
    `---[31.923302ms] com.sun.proxy.$Proxy120:QueryLatePhoto()

`---ts=2022-05-19 13:10:00;thread_name=pool-4-thread-5;id=66;is_daemon=false;priority=5;TCCL=org.apache.catalina.loader.ParallelWebappClassLoader@62cc7715
    `---[61.771667ms] com.sun.proxy.$Proxy120:QueryLatePhoto()

[arthas@25356]$ 
[arthas@25356]$ trace com.rfca.dao.mapper.ParkingMapper QueryLongOccupys
Press Q or Ctrl+C to abort.
Affect(class count: 2 , method count: 1) cost in 138 ms, listenerId: 14
`---ts=2022-05-19 13:10:49;thread_name=pool-4-thread-4;id=65;is_daemon=false;priority=5;TCCL=org.apache.catalina.loader.ParallelWebappClassLoader@62cc7715
    `---[64.901587ms] com.sun.proxy.$Proxy120:QueryLongOccupys()

`---ts=2022-05-19 13:11:23;thread_name=pool-4-thread-5;id=66;is_daemon=false;priority=5;TCCL=org.apache.catalina.loader.ParallelWebappClassLoader@62cc7715
    `---[41.786277ms] com.sun.proxy.$Proxy120:QueryLongOccupys()

[arthas@25356]$ trace com.rfca.dao.mapper.ParkingMapper QueryLongEmptys
Press Q or Ctrl+C to abort.
Affect(class count: 2 , method count: 1) cost in 142 ms, listenerId: 15
`---ts=2022-05-19 13:11:54;thread_name=pool-4-thread-3;id=64;is_daemon=false;priority=5;TCCL=org.apache.catalina.loader.ParallelWebappClassLoader@62cc7715
    `---[6.182256ms] com.sun.proxy.$Proxy120:QueryLongEmptys()

[arthas@25356]$ trace com.rfca.dao.mapper.ParkingMapper QuerySys
Press Q or Ctrl+C to abort.
Affect(class count: 2 , method count: 1) cost in 144 ms, listenerId: 16
`---ts=2022-05-19 13:12:25;thread_name=pool-4-thread-4;id=65;is_daemon=false;priority=5;TCCL=org.apache.catalina.loader.ParallelWebappClassLoader@62cc7715
    `---[18.25196ms] com.sun.proxy.$Proxy120:QuerySys()

[arthas@25356]$ trace com.rfca.dao.mapper.ParkingMapper historicalpaymentrate
Press Q or Ctrl+C to abort.
Affect(class count: 2 , method count: 1) cost in 142 ms, listenerId: 17
`---ts=2022-05-19 13:13:04;thread_name=pool-4-thread-3;id=64;is_daemon=false;priority=5;TCCL=org.apache.catalina.loader.ParallelWebappClassLoader@62cc7715
    `---[4663.98636ms] com.sun.proxy.$Proxy120:historicalpaymentrate()

[arthas@25356]$ trace com.rfca.dao.mapper.ParkingMapper paymentrateByTime
Press Q or Ctrl+C to abort.
Affect(class count: 2 , method count: 1) cost in 140 ms, listenerId: 18
`---ts=2022-05-19 13:13:47;thread_name=pool-4-thread-9;id=6a;is_daemon=false;priority=5;TCCL=org.apache.catalina.loader.ParallelWebappClassLoader@62cc7715
    `---[9.511763ms] com.sun.proxy.$Proxy120:paymentrateByTime()

`---ts=2022-05-19 13:14:16;thread_name=pool-4-thread-8;id=69;is_daemon=false;priority=5;TCCL=org.apache.catalina.loader.ParallelWebappClassLoader@62cc7715
    `---[6.436025ms] com.sun.proxy.$Proxy120:paymentrateByTime()

由以上结果分析可知
trace com.rfca.dao.mapper.ParkingMapper historicalpaymentrate

这个类的历史查询接口返回需要4秒多 需要优化 ,

QueryChargeRate11 方法需要7秒需要优化

原7秒的sql

<!--        SELECT-->
<!--        t_parking_record.parkinglotid AS id,SUM(t_charge_record.money) AS VALUE ,SUM(t_charge_record.receivable) AS total-->
<!--        FROM  t_charge_record LEFT JOIN t_parking_record ON  t_charge_record.parkingrecordid = t_parking_record.id-->
<!--        LEFT JOIN t_parkinglot ON t_parkinglot.id = t_parking_record.parkinglotid-->
<!--        where-->
<!--        t_parking_record.state > -1-->
<!--        <if test="start_date !=null">-->
<!--            and t_charge_record.modifytime &gt; #{start_date}-->
<!--        </if>-->
<!--        <if test="list !=null and list.size > 0 ">-->
<!--            and t_parkinglot.parkinglotno in-->
<!--            <foreach item="item" index="index" collection="list" open="("-->
<!--                     separator="," close=")">-->
<!--                #{item}-->
<!--            </foreach>-->
<!--        </if>-->
<!--        GROUP BY t_parking_record.parkinglotid-->

优化思路,通过小表驱动大表的思路先把查询结果找出在进行join

    SELECT  t_parking_record.parkinglotid AS id,
        SUM(b.money) AS VALUE ,
        SUM(b.receivable) AS total
        FROM (SELECT  a.parkingrecordid,a.money,a.receivable FROM t_charge_record AS a WHERE a.modifytime &gt; #{start_date}) AS b
        LEFT JOIN t_parking_record ON  b.parkingrecordid = t_parking_record.id
        LEFT JOIN t_parkinglot ON t_parkinglot.id = t_parking_record.parkinglotid
        WHERE
        t_parking_record.state > -1

        GROUP BY t_parking_record.parkinglotid

优化后 505ms

4秒的原sql

  SELECT b.`parkinglotid` as id,SUM(receivable) AS total,SUM(proceeds) AS proceeds FROM ( SELECT t.id  FROM  t_parkinglot t WHERE 1=1
        <if test="list !=null and list.size > 0 ">
            and t.parkinglotno in
            <foreach item="item" index="index" collection="list" open="("
                     separator="," close=")">
                #{item}
            </foreach>
        </if>
        )AS a
        LEFT JOIN t_parking_record b ON  a.id = b.parkinglotid
        AND b.state > -1
        <if test="start_date !=null">
            and b.outtime &gt; #{start_date} and b.outtime &lt; #{end_date}
        </if>
        GROUP BY b.parkinglotid

这个sql慢的原始是查询了半年的时间,扫描行数2千万行,又因为使用GROUP BY sum等操作没有使用索引 索引 使用索引覆盖原理 添加索引 outtime state parkinglotid receivable proceeds ,
条件优化
直接使用 parkinglotid 查询没有使用 parkinglotno
优化后 814 ms

这种方式如果还是不行,查询结果太大的话直接使用
使用 SQL_BIG_RESULT 进行优化 直接走文件排序 少了内存到 文件的复制操作

如果上述结果还是很慢
扩展
5以上都不行 前期就应该建立分库分表 或者使用ck nosql 进行查询

本次优化结果性能提升 90%

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
PL/SQL Developer是一个集成开发环境,专门面向Oracle数据库存储程序单元的开发。如今,有越来越多的商业逻辑和应用逻辑转向了Oracle Server,因此,PL/SQL编程也成了整个开发过程的一个重要组成部分。PL/SQL Developer侧重于易用性、代码品质和生产力,充分发挥Oracle应用程序开发过程中的主要优势。 主要特性    登录界面PL/SQL编辑器,具有语法加强、SQL和PL/SQL帮助、对象描述、代码助手、编译器提示、PL/SQL完善、代码内容、代码分级、浏览器按钮、超链接导航、宏库等许多智能特性,能够满足要求性最高的用户需求。当您需要某个信息时,它将自动出现,至多单击即可将信息调出。 重要功能 集成调试器   该调试器(要求Oracle 7.3.4或更高)提供您所需要的全部特性:跳入(Step In)、跳过(Step Over)、跳出(Step Out)、异常时停止运行、断点、观察和设置变量、观察全部堆栈等。基本能够调试任何程序单元(包括触发器和Oracle8 对象类型),无需作出任何修改。 PL/SQL完善器   该完善器允许您通过用户定义的规则对SQL和PL/SQL代码进行规范化处理。在编译、保存、打开一个文件时,代码将自动被规范化。该特性提高了您编码的生产力,改善了PL/SQL代码的可读性,促进了大规模工作团队的协作。 SQL 窗口   该窗口允许您输入任何SQL语句,并以栅格形式对结果进行观察和编辑,支持按范例查询模式,以便在某个结果集合中查找特定录。另外,还含有历史缓存,您可以轻松调用先前执行过的SQL语句。该SQL编辑器提供了同PL/SQL编辑器相同的强大特性。 命令窗口   使用PL/SQL Developer 的命令窗口能够开发并运行SQL脚本。该窗口具有同SQL*Plus相同的感观,另外还增加了一个内置的带语法加强特性的脚本编辑器。这样,您就可以开发自己的脚本,无需编辑脚本/保存脚本/转换为SQL*Plus/运行脚本过程,也不用离开PL/SQL Developer集成开发环境。 报告   PL/SQL Developer提供内置的报告功能,您可以根据程序数据或Oracle字典运行报告。PL/SQL Developer本身提供了大量标准报告,而且您还可以方便的创建自定义报告。自定义报告将被保存在报告文件中,进而包含在报告菜单内。这样,运行您自己经常使用的自定义报告就非常方便。   您可以使用Query Reporter免费软件工具来运行您的报告,不需要PL/SQL Developer,直接从命令行运行即可。 工程   PL/SQL Developer内置的工程概念可以用来组织您的工作。一个工程包括源文件集合、数据库对象、notes和选项。PL/SQL Developer允许您在某些特定的条目集合范围之内进行工作,而不是在完全的数据库或架构之内。这样,如果需要编译所有工程条目或者将工程从某个位置或数据库移动到其他位置时,所需工程条目的查找就变得比较简单。 To-Do条目   您可以在任何SQL或PL/SQL源文件中使用To-Do条目快速录该文件中那些需要进行的事项。以后能够从To-Do列表中访问这些信息,访问操作可以在对象层或工程层进行。 对象浏览器   可配置的树形浏览能够显示同PL/SQL开发相关的全部信息,使用该浏览器可以获取对象描述、浏览对象定义、创建测试脚本以便调试、使能或禁止触发器或约束条件、重新编译不合法对象、查询或编辑表格、浏览数据、在对象源中进行文本查找、拖放对象名到编辑器等。   此外,该对象浏览器还可以显示对象之间的依存关系,您可以递归的扩展这些依存对象(如包参考检查、浏览参考表格、图表类型等)。 性能优化   使用PL/SQL Profiler,可以浏览每一执行的PL/SQL代码行的时序信息(Oracle8i或更高),从而优化您SQL和PL/SQL的代码性能。   更进一步,您还可以自动获取所执行的SQL语句和PL/SQL程序统计信息。该统计信息包括CPU使用情况、块I/O、录I/O、表格扫描、分类等。 HTML指南   Oracle目前支持HTML格式的在线指南。您可以将其集成到PL/SQL Developer工作环境中,以便在编辑、编译出错或运行时出错时提供内容敏感帮助。 非PL/SQL对象   不使用任何SQL,您就可以对表格、序列、符号、库、目录、工作、队列、用户和角色进行浏览、创建和修改行为。PL/SQL Developer提供了一个简单易用的窗体,只要将信息输入其中,PL/SQL Developer就将生成相应的SQL,从而创建或转换对象。 模板列表   PL/SQL Developer的模板列表可用作一个实时的帮助组件,

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晴天M雨天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值