• 小哥,你写的SQL执行太慢了!


    聊聊SQL优化分析过程。

    技术人人都可以磨炼,但处理问题的思路和角度各有不同,希望这篇文章可以抛砖引玉。

    以一个例子为切入点


    一、问题背景

    某业务模块反馈SQL慢,优化过程中的一些思考做个记录。

    基础环境:

    • 主机类型:阿里云 

    • 操作系统:CentOS release 7.4

    • 存储:EMC

    • 内存:64 G

    • CPU型号:Intel(R) Xeon(R) Platinum 8163 CPU @ 2.50GHz ( 1 U * 8 core) 

    • CPU核数:16CORE

    • 数据库环境:11.2.0.4

    问题现象:

    慢SQL

    简单说明:

    在很多应用场景中,SQL 的性能直接决定了系统的性能。此外,查询速度慢并不只是因为 SQL 语句本身,还可能是因为内存分配不佳、文件结构不合理、优化器判断异常等其他原因。

    本文介绍一些通过调整 SQL 语句就能优化SQL的通用小技巧,优化 SQL 的方法不能解决所有的性能问题,但是却能处理很多因 SQL 写法不合理而产生的性能问题。

    二、分析说明

    • 通过分析定位慢SQL,分析慢SQL原因;

    • 追溯SQL执行历史数据,分析关键指标在SQL多次执行的波动,这些关键指标可以用来做为SQL健康度参考指标。

    • 用实际数据来验证推断,排除掉其它干扰因素,定位SQL慢的根本原因,帮助快速修复。

    三、疑问点排查及分析思路

    1、原SQL结构如下:

    select ... from ...where( (     order_creation_date>= to_date(20120208,'yyyy-mm-dd') and order_creation_date ) or (     send_date>= to_date(20120208,'yyyy-mm-dd') and send_date ))andnvl(a.bd_id,0) = 1

    业务需求我看了一下,还真不能怪开发小哥这么写。

    2、SQL执行计划

    从执行计划(Pstart、Pstop)中可以看出来,SQL涉及了一个分区表,扫描了所有分区。

    3、如何改写?

    找到了原因,下一步就是改写SQL了。

    两个思路:

    第一通过union all把原来的SQL拆分;

    第二通过调整日期格式,使分区特性起效。

    尝试改写为:​​​​​​​

    select ...from ...where order_creation_date >= to_date(20120208,'yyyy-mm-dd') and order_creation_dateunion allselect ...from ...wheresend_date>= to_date(20120208,'yyyy-mm-dd') and send_datenvl(a.bd_id,0) = 5

    改写后SQL执行计划如下:

    效果还不错,缺点是扫描了两遍表,SQL性能得到了很大提升,执行时间从1个多小时缩减到1分钟。

    总结

    1、通过使用union all,简化条件判断。

    2、规范SQL的写法:对于非标准的日期格式,Oracle在复杂逻辑判断的情况下分区特性会失效。这种情况下,会走全表扫描,结果是正确的,但是执行效率会很低。

  • 相关阅读:
    简·奥斯汀社会作文比赛冲藤必备
    QT5-布局在创作中的理解应用
    【Mybatis小白从0到90%精讲】01:IDEA创建Maven项目,添加Mybatis依赖
    笔记:Python 字符串与正则表达式(练习题)
    【JMeter】jmeter测试 - 上传多个图片/批量上传图片接口 CSV文件参数化方法
    sql报错注入和联合注入
    命令行远程操作windows
    创业可以做什么项目,六个轻资产创业项目推荐
    getBoundingClientRect使用场景(table固定表头)
    【网络安全 --- PHP基础】学网安PHP语言所涉及到的知识,来看看吧,看着一篇文章就够了,建议收藏学习!!!
  • 原文地址:https://blog.csdn.net/m0_38048955/article/details/126836207