- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
为什么 oracle 总是解析下面的查询?
select MY_SEQUENCE_SEQ.nextval
from dual
来自 Quest SQL Optimizer (8.6.0) 的 SGA 统计数据:
Executions : 83630
Parse_calls: 83630
序列详细信息:
测试场景:
创建音序器:
CREATE SEQUENCE MY_SEQUENCE_SEQ
START WITH 1
MAXVALUE 999999999999999999999999999
MINVALUE 1
NOCYCLE
CACHE 20
NOORDER;
对有权访问 v$sql View 的用户执行此查询。
select executions,
parse_calls
from v$sql
where sql_text like 'select MY_SEQ%';`
执行n次序列查询
从点 2 开始执行查询。
得到的结果:
EXECUTIONS - n
PARSE_CALSS - n
测试于:
数据库:Oracle 数据库 10g 版本 10.2.0.4.0 - 64 位生产
客户端:Toad 版本 11.5.1.2
最佳答案
这不是 Oracle 的错误,这只是 TOAD 将 SQL 发送到 oracle 的方式。即toad 不会将语句句柄缓存到oracle,它只是在完成时将其关闭。
当查询发送到 SQL 引擎时,Oracle 将对查询执行三个主要操作之一。
即我们希望处于情况 3 而我们当然不希望处于情况 1!那么每种情况会在什么时候发生?
当 SQL 根本不在共享池中或 SQL 在共享池中但使用的绑定(bind)变量/文字意味着当前 SQL 不可用时,将发生硬解析。例如,假设我们发出此 SQL 三次 select MY_SEQUENCE_SEQ.nextval from dual
。这将在 Oracle 第一次看到此 SQL 并将其放入共享池时进行硬解析,并将在第 2 次和第 3 次调用时进行软解析。我们可以很容易地看到这种情况发生:
SQL> select n.name, s.value from v$mystat s, v$statname n where n.statistic# = s.statistic# and n.name in ('parse count (hard)', 'parse count (total)');
NAME VALUE
-------------------- ----------
parse count (total) 522
parse count (hard) 287
SQL> select /* test1 */ MY_SEQUENCE_SEQ.nextval
2 from dual;
NEXTVAL
----------
62
SQL> select /* test1 */ MY_SEQUENCE_SEQ.nextval
2 from dual;
NEXTVAL
----------
63
SQL> select /* test1 */ MY_SEQUENCE_SEQ.nextval
2 from dual;
NEXTVAL
----------
64
SQL> select n.name, s.value from v$mystat s, v$statname n where n.statistic# = s.statistic# and n.name in ('parse count (hard)', 'parse count (total)');
NAME VALUE
-------------------- ----------
parse count (total) 526
parse count (hard) 288
SQL> select sql_text, executions, parse_calls from v$sql where sql_text like 'select /* test1 */%';
SQL_TEXT EXECUTIONS PARSE_CALLS
------------------------------ ---------- -----------
select /* test1 */ MY_SEQUENCE 3 3
_SEQ.nextval from dual
硬解析加一,sql 注册了 3 次解析,所以 1 次硬解析(将其放入共享池)和 2 次软解析。
为什么要软解析?为了“不解析”发生,客户端代码必须保留语句句柄并重新执行它。也就是说,如果我们用 Java 编写这个,我们会这样写:
public static int getNextSeq(String str)
throws Exception
{
if (sel == null)
{
sel = con.prepareStatement("select MY_SEQUENCE_SEQ.nextval v from dual "+str);
}
ResultSet rs = sel.executeQuery();
int seqVal=0;
while (rs.next())
{
seqVal = rs.getInt("V");
}
return seqVal;
}
即如果我们还没有这样做,我们只会调用 PrepareStatement。如果我们用
执行这段代码System.out.println(getNextSeq(args[0]));
System.out.println(getNextSeq(args[0]));
System.out.println(getNextSeq(args[0]));
我们可以在实际中看到这一点:
SQL> host java Prep two
70
71
72
SQL> select sql_text, executions, parse_calls from v$sql where sql_text like 'select %two';
SQL_TEXT EXECUTIONS PARSE_CALLS
------------------------------ ---------- -----------
select MY_SEQUENCE_SEQ.nextval 3 1
v from dual two
现在除了 1 次硬解析外,oracle 没有解析 SQL。如果 Java 代码写得不好,我们会看到:
sel = con.prepareStatement("select MY_SEQUENCE_SEQ.nextval v from dual "+str);
ResultSet rs = sel.executeQuery();
SQL> host java Prep three
73
74
75
SQL> select sql_text, executions, parse_calls from v$sql where sql_text like 'select %three';
SQL_TEXT EXECUTIONS PARSE_CALLS
------------------------------ ---------- -----------
select MY_SEQUENCE_SEQ.nextval 3 3
v from dual three
现在我们看到解析计数 = 执行。换句话说,我们正在软解析每个不理想的调用。同样不是 Oracle 限制,只是客户端实现不佳。
有了 PL/SQL,我们就不必担心这个了。为什么? PL/SQL 不解析,因为它为运行 SQL 做了很多优化(不出所料!)。例如:
SQL> declare
2 v_seq number;
3 begin
4 for idx in 1..3 loop
5 select MY_SEQUENCE_SEQ.nextval into v_seq from dual pls_test;
6 end loop;
7 end;
8 /
PL/SQL procedure successfully completed.
SQL> select sql_text, executions, parse_calls from v$sql where sql_text like 'SELECT %PLS_TEST';
SQL_TEXT EXECUTIONS PARSE_CALLS
------------------------------ ---------- -----------
SELECT MY_SEQUENCE_SEQ.NEXTVAL 3 1
FROM DUAL PLS_TEST
现在,pl/sql 为我们进行这种优化时有一个警告,那就是参数 SESSION_CACHED_CURSORS。在给定的 session 中,Oracle 将为我们保持打开一组游标(即它们是软打开的,也就是说,如果我们需要更多游标,它将关闭它们)。所以如果我们有 SESSION_CACHED_CURSORS=0 并重复上面的测试,我们会看到软解析突然出现:
SQL> alter session set session_cached_cursors=0;
Session altered.
SQL> declare
2 v_seq number;
3 begin
4 for idx in 1..3 loop
5 select MY_SEQUENCE_SEQ.nextval into v_seq from dual pls_test2;
6 end loop;
7 end;
8 /
PL/SQL procedure successfully completed.
SQL> select sql_text, executions, parse_calls from v$sql where sql_text like 'SELECT %PLS_TEST2';
SQL_TEXT EXECUTIONS PARSE_CALLS
------------------------------ ---------- -----------
SELECT MY_SEQUENCE_SEQ.NEXTVAL 3 3
FROM DUAL PLS_TEST2
显然,缓存游标的值越高,我们就越有机会避免软解析并达到完全避免解析的 chalice 。
关于oracle - oracle 解析器如何处理序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13826105/
我之前让 dll 注入(inject)器变得简单,但我有 Windows 7,我用 C# 和 C++ 做了它,它工作得很好!但是现在当我在 Windows 8 中尝试相同的代码时,它似乎没有以正确的方
我正在尝试制作一个名为 core-splitter 的元素,该元素在 1.0 中已弃用,因为它在我们的项目中起着关键作用。 如果您不知道 core-splitter 的作用,我可以提供一个简短的描述。
我有几个不同的蜘蛛,想一次运行所有它们。基于 this和 this ,我可以在同一个进程中运行多个蜘蛛。但是,我不知道如何设计一个信号系统来在所有蜘蛛都完成后停止 react 器。 我试过了: cra
有没有办法在达到特定条件时停止扭曲 react 器。例如,如果一个变量被设置为某个值,那么 react 器应该停止吗? 最佳答案 理想情况下,您不会将变量设置为一个值并停止 react 器,而是调用
https://code.angularjs.org/1.0.0rc9/angular-1.0.0rc9.js 上面的链接定义了外部js文件,我不知道Angular-1.0.0rc9.js的注入(in
我正在尝试运行一个函数并将服务注入(inject)其中。我认为这可以使用 $injector 轻松完成.所以我尝试了以下(简化示例): angular.injector().invoke( [ "$q
在 google Guice 中,我可以使用函数 createInjector 创建基于多个模块的注入(inject)器。 因为我使用 GWT.create 在 GoogleGin 中实例化注入(in
我在 ASP.NET Core 1.1 解决方案中使用配置绑定(bind)。基本上,我在“ConfigureServices Startup”部分中有一些用于绑定(bind)的简单代码,如下所示: s
我在 Spring MVC 中设置 initBinder 时遇到一些问题。我有一个 ModelAttribute,它有一个有时会显示的字段。 public class Model { privat
我正在尝试通过jquery post发布knockoutjs View 模型 var $form = $('#barcodeTemplate form'); var data = ko.toJS(vm
如何为包含多态对象集合的复杂模型编写自定义模型绑定(bind)程序? 我有下一个模型结构: public class CustomAttributeValueViewModel { publi
您好,我正在尝试实现我在 this article 中找到的扩展方法对于简单的注入(inject)器,因为它不支持开箱即用的特定构造函数的注册。 根据这篇文章,我需要用一个假的委托(delegate)
你好,我想自动注册我的依赖项。 我现在拥有的是: public interface IRepository where T : class public interface IFolderReposi
我正在使用 Jasmine 测试一些 Angular.js 代码。为此,我需要一个 Angular 注入(inject)器: var injector = angular.injector(['ng'
我正在使用 Matlab 代码生成器。不可能包含代码风格指南。这就是为什么我正在寻找一个工具来“ reshape ”、重命名和重新格式化生成的代码,根据我的: 功能横幅约定 文件横幅约定 命名约定 等
这个问题在这里已经有了答案: Where and why do I have to put the "template" and "typename" keywords? (8 个答案) 关闭 8
我开发了一种工具,可以更改某些程序的外观。为此,我需要在某些进程中注入(inject)一个 dll。 现在我基本上使用这个 approach .问题通常是人们无法注入(inject) dll,因为他们
我想使用 swing、spring 和 hibernate 编写一个 java 应用程序。 我想使用数据绑定(bind)器用 bean 的值填充 gui,并且我还希望它反射(reflect) gui
我有这段代码,当两个蜘蛛完成后,程序仍在运行。 #!C:\Python27\python.exe from twisted.internet import reactor from scrapy.cr
要点是 Spring Batch (v2) 测试框架具有带有 @Autowired 注释的 JobLauncherTestUtils.setJob。我们的测试套件有多个 Job 类提供者。因为这个类不
我是一名优秀的程序员,十分优秀!