SQL解析...没有什么大不了的?#oracle(译文)

简介: 在Oracle中编写SQL语句时,我们都强调使用共享SQL的重要性,换种说法是:在适当的情况下使用绑定变量,我们大多数人可能都已经看过关于这个原则的标准演示。经典的演示是比较两个类似的脚本,其中一个使用生成大量包含字面量的 SQL 语句,另一个使用绑定变量重新重写相同的脚本以获得显著的改进

在Oracle中编写SQL语句时,我们都强调使用共享SQL的重要性,换种说法是:在适当的情况下使用绑定变量,我们大多数人可能都已经看过关于这个原则的标准演示。经典的演示是比较两个类似的脚本,其中一个使用生成大量包含字面量的 SQL 语句,另一个使用绑定变量重新重写相同的脚本以获得显著的改进。这是我编写的一个简单例子:


SQL> create table t ( x int primary key) organization index;
Table created.
SQL> insert into t  2  select rownum from dual  3  connect by level <= 100000;
100000 rows created.
SQL> exec dbms_stats.gather_table_stats('','T');
PL/SQL procedure successfully completed.
SQL> set timing onSQL> declare  2    v int;  3  begin  4    for i in 1 .. 100000 loop  5      select x into v from t where x = i;  6    end loop;  7  end;  8  /
PL/SQL procedure successfully completed.
Elapsed: 00:00:01.56
SQL> set timing onSQL> declare  2    v int;  3  begin  4    for i in 1 .. 100000 loop  5      execute immediate 'select x from t where x = '||i into v;  6    end loop;  7  end;  8  /
PL/SQL procedure successfully completed.
Elapsed: 00:01:04.92

所以通常接下来是手指着花费的时间“看看绑定变量有多棒,看看使用字面量的SQL有多糟糕!”

但最近,有人乐于反驳,即“那又怎样?”他们的观点是:在“糟糕”的示例中,我们每秒执行大约 1600 个语句。这和绑定变量一样好吗?当然不是...但是谁在乎呢?有很多系统每秒 16 个语句就可以了,更不用说 1600 个了。那么,有必要对绑定变量的性能提升大惊小怪吗?虽然这样的观点在其他方面站不住脚——比如多用户场景下的latch的争用,还有SQL注入的风险,但我不会重新强调这些,让我们看看“性能已经够用了”的观点能不能站住脚。

我们不要忘记第一次“绑定变量与字面量”脚本出来的时代。对我个人而言,在90年代初,我的Oracle数据库(版本7)运行在Sparcstation 10上,它具有非常强大且非常昂贵的50 Mhz处理器!😀 (大家可到维基百科上重温一下回忆:https://en.wikipedia.org/wiki/SPARCstation_10 )


因此,在那些日子里,绑定变量和字面量之间的差异是巨大的,因为CPU处理器的周期非常有价值。但我们往往会忘记,正如处理器的发展一样,我们对访问数据的需求也在发展。是的,现代处理器确实可以轻松地处理那些基于字面量的简单主键查找SQL。但现在的SQL并不总是这么简单,如今,SQL就像

处理器一样不断发展——它们可能要复杂得多。那么解析成本会怎样呢?因此,让我们引入一些复杂性,并使用一些更复杂的SQL重新运行我们的测试。

显然,复杂的SQL可能具有很长的执行时间,因此我们将通过使用DBMS_SQL仅解析,而不执行SQL。我们在SQL中将包括几个字典视图,这些视图本身就包含多个字典视图,因此即使SQL只是一个简单的联接,也存在很大的复杂性。





SQL> set timing onSQL> declare  2    c int;  3  begin  4   c := dbms_sql.open_cursor;  5   for i in 1 .. 100000 loop  6      dbms_sql.parse(c,  7        q'{  8        select o.object_name, o.last_ddl_time, sum(s.bytes)  9        from   all_objects o, 10               dba_segments s 11        where  o.owner = s.owner 12        and    o.object_name = s.segment_name 13        and    o.object_type = 'TABLE' 14        and    o.object_id = :1 15        group by o.object_name, o.last_ddl_time 16        }', 17        dbms_sql.native ); 18    end loop; 19    dbms_sql.close_cursor(c); 20  end; 21  /
PL/SQL procedure successfully completed.
Elapsed: 00:00:01.14
SQL> declare  2    c int;  3  begin  4   c := dbms_sql.open_cursor;  5   for i in 1 .. 100000 loop  6      dbms_sql.parse(c,  7        q'{  8        select o.object_name, o.last_ddl_time, sum(s.bytes)  9        from   all_objects o, 10               dba_segments s 11        where  o.owner = s.owner 12        and    o.object_name = s.segment_name 13        and    o.object_type = 'TABLE' 14        and    o.object_id = }'||i|| 15        q'{ 16        group by o.object_name, o.last_ddl_time 17        }', 18        dbms_sql.native ); 19    end loop; 20    dbms_sql.close_cursor(c); 21  end; 22  /
PL/SQL procedure successfully completed.
Elapsed: 10:07:12.71

是的...你没看错!超过 10 个小时来完成所有这些SQL的解析。

所以不能因为CPU变得更加强大和聪明,就忽视了不带绑定变量的SQL对系统的伤害!

京东购物

欢迎购买号主的专著



目录
打赏
0
0
0
0
12
分享
相关文章
SQL注入之万能密码:原理、实践与防御全解析
本文深入解析了“万能密码”攻击的运行机制及其危险性,通过实例展示了SQL注入的基本原理与变种形式。文章还提供了企业级防御方案,包括参数化查询、输入验证、权限控制及WAF规则配置等深度防御策略。同时,探讨了二阶注入和布尔盲注等新型攻击方式,并给出开发者自查清单。最后强调安全防护需持续改进,无绝对安全,建议使用成熟ORM框架并定期审计。技术内容仅供学习参考,严禁非法用途。
448 0
解决大小写、保留字与特殊字符问题!Oracle双引号在SQL中的特殊应用
在Oracle数据库开发中,双引号的使用是一个重要但易被忽视的细节。本文全面解析了双引号在SQL中的特殊应用场景,包括解决标识符与保留字冲突、强制保留大小写、支持特殊字符和数字开头标识符等。同时提供了最佳实践建议,帮助开发者规避常见错误,提高代码可维护性和效率。
147 6
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
【YashanDB知识库】yashandb执行包含带oracle dblink表的sql时性能差
【YashanDB知识库】yashandb执行包含带oracle dblink表的sql时性能差
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
本文来自YashanDB官网,介绍如何处理Oracle客户端sql*plus中使用@@调用同级目录SQL脚本的场景。崖山数据库23.2.x.100已支持@@用法,但旧版本可通过Python脚本批量重写SQL文件,将@@替换为绝对路径。文章通过Oracle示例展示了具体用法,并提供Python脚本实现自动化处理,最后调整批处理脚本以适配YashanDB运行环境。
如何在 Oracle 中配置和使用 SQL Profiles 来优化查询性能?
在 Oracle 数据库中,SQL Profiles 是优化查询性能的工具,通过提供额外统计信息帮助生成更有效的执行计划。配置和使用步骤包括:1. 启用自动 SQL 调优;2. 手动创建 SQL Profile,涉及收集、执行调优任务、查看报告及应用建议;3. 验证效果;4. 使用 `DBA_SQL_PROFILES` 视图管理 Profile。
如何在 Java 代码中使用 JSqlParser 解析复杂的 SQL 语句?
大家好,我是 V 哥。JSqlParser 是一个用于解析 SQL 语句的 Java 库,可将 SQL 解析为 Java 对象树,支持多种 SQL 类型(如 `SELECT`、`INSERT` 等)。它适用于 SQL 分析、修改、生成和验证等场景。通过 Maven 或 Gradle 安装后,可以方便地在 Java 代码中使用。
1756 11
canal-starter 监听解析 storeValue 不一样,同样的sql 一个在mybatis执行 一个在数据库操作,导致解析不出正确对象
canal-starter 监听解析 storeValue 不一样,同样的sql 一个在mybatis执行 一个在数据库操作,导致解析不出正确对象
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
388 29

热门文章

最新文章

推荐镜像

更多
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问