分享

SQL执行速度优化案例

本帖最后由 levycui 于 2022-9-6 18:06 编辑
问题导读:
1、问题背景是什么?
2、如何进行问题分析?
3、疑问点排查及分析思路是什么?
4、有哪些优化点?

聊聊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结构如下:
  1. select ... from ...
  2. where
  3. (
  4.     (
  5.      order_creation_date>= to_date(20120208,'yyyy-mm-dd') and
  6.     order_creation_date<to_date(20120209,'yyyy-mm-dd')
  7.     )
  8. or
  9.     (
  10.      send_date>= to_date(20120208,'yyyy-mm-dd') and send_date<to_date(20120209, 'yyyy-mm-dd')
  11.     )
  12. )
  13. andnvl(a.bd_id,0) = 1
复制代码

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

2、SQL执行计划

2022-09-06_175910.jpg

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

3、如何改写?

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

两个思路:

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

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


尝试改写为:
  1. select ...
  2. from ...
  3. where
  4.     order_creation_date >= to_date(20120208,'yyyy-mm-dd') and
  5.     order_creation_date<to_date(20120209,'yyyy-mm-dd')
  6. union all
  7. select ...
  8. from ...
  9. where
  10. send_date>= to_date(20120208,'yyyy-mm-dd') and
  11.     send_date<to_date(20120209,'yyyy-mm-dd') and
  12. nvl(a.bd_id,0) = 5
复制代码

改写后SQL执行计划如下:

2022-09-06_175950.jpg


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


总结

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

作者:阿陶学长
来源:https://mp.weixin.qq.com/s/zvIjG1jgieE7WV2xm_kcZw


最新经典文章,欢迎关注公众号


没找到任何评论,期待你打破沉寂

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条