113- 关于SQL写法的一些传言和坏习惯,我在两本书上找到了出处

2024年 7月 1日 60.6k 0

这篇文章放在草稿箱里面很长时间了,直到最近又看到了这篇多个公号转发过的神文:《公司新来一个技术总监:谁再在 SQL 中写 in 和 not in,直接走人!》. 

下面有几个说法, 分别来自两本SQL入门经典书, 我认为不太妥当:

1-1.关于子查询用exists还是in的问题, 书上说exists比in写法效率高:113- 关于SQL写法的一些传言和坏习惯,我在两本书上找到了出处-1

作者给出的例子:

113- 关于SQL写法的一些传言和坏习惯,我在两本书上找到了出处-2

作者对上述结论做了解释:

113- 关于SQL写法的一些传言和坏习惯,我在两本书上找到了出处-3

老虎刘点评:

    这本书是2017年出版的中译本,原书是哪一年出版我不太清楚.最后一句话我还是比较认可的.

    oracle数据库从9i开始就支持自动查询转换, 常规写法的 in和exists, 经过优化器的查询转换后,执行计划是一样的.  有几种特殊情况, in写法的效率反而要高于exists,从另一个角度说明优化器还是考虑得不够周到. 

   至于not in和not exists两种写法,如果关联字段都有not null约束, 也是一样的, 但是很多时候没有这个not null的约束或条件,二者在逻辑上就不是等价的. 大部分情况还是建议使用not exists. 我在之前的文章有说明,文章链接 : 102-not in和not exists到底选哪个?这个问题有点复杂,但是结论很简单,不要被专家们带偏了。

    其他数据库,比如mysql,从8.0版本开始支持in/exists的自动转换; postgresql 多年前的版本也已经支持in/exists的自动转换了. 可能也有特殊情况, 特殊对待即可. 

1-2. 使用非等值自关联, 计算产品价格排名情况:

113- 关于SQL写法的一些传言和坏习惯,我在两本书上找到了出处-4

老虎刘点评:

    如果一个只有几万条记录的表,用这种非等值关联的写法, 消耗的资源和时间都是很大的(类似笛卡尔集). 书上用这种写法只考虑了功能的实现, 完全没有考虑性能. 也有可能是当时使用的数据库不支持分析函数(常见数据库, 较晚支持分析函数的应该只有mysql了).

以上内容来自2017年11月出版的的:

(基于oracle 10g, SQL server 2005, DB2 9.1 , PG 9.6 , Mysql 5.0)

113- 关于SQL写法的一些传言和坏习惯,我在两本书上找到了出处-5

再看另一本书的内容:

2-1 用标量子查询写法计算每个客户订单数:

113- 关于SQL写法的一些传言和坏习惯,我在两本书上找到了出处-6

老虎刘点评:

    很多开发人员喜欢使用这种标量子查询的写法, 这种写法写起来非常顺手,但是很多时候会影响SQL的执行效率.改成外关联一般是比较好的选择.

2-2 使用union做 or 的改写:

113- 关于SQL写法的一些传言和坏习惯,我在两本书上找到了出处-7

老虎刘点评:

    逻辑上不等价,还增加了去重的额外操作,影响性能. 正确的改写方法应该用union all, 比如union all的上半部分增加 and( cust_name 'Fun4All' or cust_name is null)

以上内容来自2020年出版的第5版:

113- 关于SQL写法的一些传言和坏习惯,我在两本书上找到了出处-8

上面提到的两本书, 重点讲述功能的实现,作为SQL入门是一个不错的选择.但是如果要从中学习性能优化相关内容,就不太适合了. 

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论