暂无图片
暂无图片
2
暂无图片
暂无图片
暂无图片

课程笔记 | 【大咖课堂】老虎刘谈Oracle性能优化 | 7.10 这些SQL调优小"技巧",你学废了吗?

原创 严少安 2022-08-26
783

20220826_221028.png

谈谈这节课的学习心得:

  1. CBO

oracle 版本10g(2003年发布)开始,默认和推荐的OPTIMIZER_MODE就是ALL_ROWS了(CBO)

主流数据库现在都是 CBO 了,那么在 CBO 基础之上,如何做 hint 就是很重要的调优手段,熟练掌握各个 hint 的用法和使用场景,也是 DBA 应该掌握的技能之一。

  1. 访问Table的方式

这里首先要搞清楚是行存表还是列存表,以及存储模型,是 IOT 还是 LSM。

  1. 选择最有效率的表名顺序(只在基于规则的优化器中有效)

表的顺序随便写,优化器会根据统计信息,自动选择关联顺序和关联方法.

但在使用 left/right join 这种外连接时,还是需要注意分辨驱动表的。

  1. SELECT子句中避免使用 ‘*’

1.exadata 存储节点有字段投影功能, 减少字段数能减少传输到计算节点的数据量,降低计算节点处理效率
2.如果包含lob字段,如果不需要处理该字段, 造成大量的多余物理读和网络流量(而且含lob字段,不能materialize)
3.hash join/merge join,字段数多会占用更多的PGA内存空间,对性能影响很大
4.可能错过了索引覆盖,对性能影响更为严重
5.造成服务端到客户端网络流量增加,传输量增大,效率就差

并未过时的注意项,只查询用得到的字段。

  1. 减少访问数据库的次数

WHERE A.EMP_NO = 342 AND B.EMP_NO = 291;
WHERE EMP_NO in (342,291);

两种写法还是有区别的,具体看数据库类型和版本,
以及执行计划,是否会受到 ICP 或是算子下推的影响。

  1. 用TRUNCATE替代DELETE

建议使用truncate而不是使用不加where条件的delete.

truncate 同样适用于分区表,可以直接清空整个分区的数据。

  1. 尽量多使用COMMIT

在批处理情况下, commit频率要适中, 每500条或1000条 commit一次(根据情况)

也是为了规避大事务,不论何种数据库,尤其是分布式数据库或类似架构,大事务都是一个大坑。

  1. 通过内部函数提高SQL效率

为了一个查询还要创建两个函数,太复杂了吧. 不用函数, 先只对EMP_HISTORY做group by,再与其他两个小表做关联

不建议使用函数,函数也是SQL编程的一种。

  1. 使用表的别名(Alias)

使用别名是个好习惯,应该写到开发规范里面. 但是使用别名主要是为了避免相同column导致的逻辑错误,解析时间和语法错误是次要的.

对于某些 SQL 严格的数据库上,对于不用表别名会出现歧义的情况,会直接将 SQL 抛错。

  1. 用索引提高效率

查询少量数据索引快,查询大量数据全表扫描快! delete和update一般情况下也是需要使用索引的,同时维护索引的开销要比全表扫描少很多;定期的rebuild索引不是必需的, 频繁的update和delete操作, 可能需要rebuild.

对于频繁全表删除并重新导入的表,建议rebuild index,否则在某些场景下,会影响 SQL 执行效率,不准的统计信息会影响 CBO。
另外,也不是索引越多越好,如果一个表的索引数量比字段数还多,那是图啥呢~

总结:

SQL优化是一个比较严谨的事情, 一些未经证实或者有明显错误的小"技巧"在网上广泛流传,不是一件好事情. 希望喜欢分享的专家们,在出版专业书籍,写博客或是公众号文章时, 也能本着严肃认真的态度,不要误导一些不明真相的群众.

理论与实践要结合,动手测试也有助于加深对理论的理解!

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论