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

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 在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对系统的伤害!

京东购物

欢迎购买号主的专著



相关文章
|
8天前
|
SQL 数据库
SQL解析相关报错
SQL解析相关报错
28 5
|
13天前
|
SQL 安全 数据库
Python Web开发者必看!SQL注入、XSS、CSRF全面解析,守护你的网站安全!
在Python Web开发中,构建安全应用至关重要。本文通过问答形式,详细解析了三种常见Web安全威胁——SQL注入、XSS和CSRF,并提供了实用的防御策略及示例代码。针对SQL注入,建议使用参数化查询;对于XSS,需对输出进行HTML编码;而防范CSRF,则应利用CSRF令牌。通过这些措施,帮助开发者有效提升应用安全性,确保网站稳定运行。
28 1
|
2月前
|
SQL 数据处理 数据库
|
2月前
|
SQL 存储 监控
|
2月前
|
SQL 关系型数据库 MySQL
|
2月前
|
数据库 Java 监控
Struts 2 日志管理化身神秘魔法师,洞察应用运行乾坤,演绎奇幻篇章!
【8月更文挑战第31天】在软件开发中,了解应用运行状况至关重要。日志管理作为 Struts 2 应用的关键组件,记录着每个动作和决策,如同监控摄像头,帮助我们迅速定位问题、分析性能和使用情况,为优化提供依据。Struts 2 支持多种日志框架(如 Log4j、Logback),便于配置日志级别、格式和输出位置。通过在 Action 类中添加日志记录,我们能在开发过程中获取详细信息,及时发现并解决问题。合理配置日志不仅有助于调试,还能分析用户行为,提升应用性能和稳定性。
38 0
|
2月前
|
SQL 安全 数据库
|
SQL 关系型数据库 Oracle
ORACLE SQL优化之ORA-03150&ORA-02055&ORA-02063
                                                                                                             >   
4842 0
|
SQL Oracle 关系型数据库
Oracle SQL优化之多表连接
Oracle SQL优化之多表连接
544 0
Oracle SQL优化之多表连接
|
SQL 存储 Oracle
Oracle SQL语句优化方法总结
  1、SQL语句尽量用大写的   因为oracle总是先解析SQL语句,把小写的字母转换成大写的再执行。   2、使用表的别名   当在SQL语句中连接多个表时, 尽量使用表的别名并把别名前缀于每个列上。这样一来,   就可以减少解析的时间并减少那些由列歧义引起的语法错误。   3、选择最有效率的表名顺序(只在基于规则的优化器(RBO)中有效)
200 0

热门文章

最新文章

推荐镜像

更多
下一篇
无影云桌面