Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 减少上下文切换_Sql_Oracle_Oracle Sqldeveloper_Query Optimization_Context Switch - Fatal编程技术网

Sql 减少上下文切换

Sql 减少上下文切换,sql,oracle,oracle-sqldeveloper,query-optimization,context-switch,Sql,Oracle,Oracle Sqldeveloper,Query Optimization,Context Switch,问题: Oracle SQL—我有两个选择查询,如SQ1和SQ2。SQ1和SQ2都选择ID值,但具有不同的联接条件、差异表和where条件 场景1:如果SQ1返回1行,则使用select语句的结果更新表。 如果SQ1返回0行或多于1行,则控制应转到场景2 场景2:如果SQ2返回1行,则使用SQ2语句的结果更新表。 如果SQ2返回0或>1结果,则调用另一个包过程 如何将最小上下文切换到数据库 我是如何编码的: 要求 对数据库的调用最少。减少上下文切换。好吧,如果没有其他信息,像这样的东西应该可以工

问题:

Oracle SQL—我有两个选择查询,如SQ1和SQ2。SQ1和SQ2都选择ID值,但具有不同的联接条件、差异表和where条件

场景1:如果SQ1返回1行,则使用select语句的结果更新表。 如果SQ1返回0行或多于1行,则控制应转到场景2

场景2:如果SQ2返回1行,则使用SQ2语句的结果更新表。 如果SQ2返回0或>1结果,则调用另一个包过程

如何将最小上下文切换到数据库

我是如何编码的:

要求


对数据库的调用最少。减少上下文切换。

好吧,如果没有其他信息,像这样的东西应该可以工作:

update t
    set col = coalesce( (<SQL1>), (<SQL2>)
    where (select count(*) from <sql1>) = 1 or
          (select count(*) from <sql2) = 1;

也就是说,我可能会修复您的筛选语句,使它们返回0或1行,永远不会超过1行。

好吧,没有其他信息,类似这样的东西应该可以工作:

update t
    set col = coalesce( (<SQL1>), (<SQL2>)
    where (select count(*) from <sql1>) = 1 or
          (select count(*) from <sql2) = 1;
也就是说,我可能会修复您的筛选语句,使它们返回0或1行,永远不会超过1行

SQ2与SQ1是相同的select语句,但带有额外的where条件

你可以只做一个这样的陈述

SELECT 
   count(*),
   count( case when ... /*additional where condition for SQ2 */ then 1 end )
INTO v_count, v_count2
FROM table
然后执行IF-then-ELSIF语句的级联:

IF v_count = 1 THEN 
   ..do this...
ELSIF v_count2=1  THEN 
   ...do that...
ELSE 
   call package.procedure. 
END IF;
这样,您可以保存1个上下文切换和1个表扫描

SQ2与SQ1是相同的select语句,但带有额外的where条件

你可以只做一个这样的陈述

SELECT 
   count(*),
   count( case when ... /*additional where condition for SQ2 */ then 1 end )
INTO v_count, v_count2
FROM table
然后执行IF-then-ELSIF语句的级联:

IF v_count = 1 THEN 
   ..do this...
ELSIF v_count2=1  THEN 
   ...do that...
ELSE 
   call package.procedure. 
END IF;


这样,您可以保存1个上下文切换和1个表扫描。

谢谢。但是该表被配置为具有多个结果和多个记录。因此,这是一个预期的场景。我们如何将SQL语句合并?这对我来说不管用me@Natty . . . 您需要一组额外的括号,就像对任何标量子查询一样。-这是我声明n int的测试代码;开始n:=合并从双重中选择1,2;dbms_output.put_亚麻布;结束@整洁时髦的这不需要PL/SQL。这只是一个SQL语句。谢谢。但是该表被配置为具有多个结果和多个记录。因此,这是一个预期的场景。我们如何将SQL语句合并?这对我来说不管用me@Natty . . . 您需要一组额外的括号,就像对任何标量子查询一样。-这是我声明n int的测试代码;开始n:=合并从双重中选择1,2;dbms_output.put_亚麻布;结束@整洁时髦的这不需要PL/SQL。这只是一条SQL语句。抱歉。我已经更新了问题。SQ1和SQ2都选择一个ID值,但是连接条件、差异表和where条件不同。答案不错,但是PL/SQL->SQL引擎的上下文切换真的那么昂贵吗?我的理解一直是关注SQL->PL/SQL开关,但PL/SQL->SQL开关在Oracle中得到了很好的优化。我怀疑OP通过这种优化使他的代码变得不必要的复杂。@Matthew McPeak您需要测试以了解确切的值,但是使用上下文切换的查询甚至比简单SQL 50倍->5000%慢30~50倍。@krokodilko这些是SQL->PL/SQL上下文切换,限制它们的需要是众所周知的。但我看到的指导是,PL/SQL->SQL,即从PL/SQL块上下文开关调用SQL语句,优化效果更好,问题更少。抱歉。我已经更新了问题。SQ1和SQ2都选择一个ID值,但是连接条件、差异表和where条件不同。答案不错,但是PL/SQL->SQL引擎的上下文切换真的那么昂贵吗?我的理解一直是关注SQL->PL/SQL开关,但PL/SQL->SQL开关在Oracle中得到了很好的优化。我怀疑OP通过这种优化使他的代码变得不必要的复杂。@Matthew McPeak您需要测试以了解确切的值,但是使用上下文切换的查询甚至比简单SQL 50倍->5000%慢30~50倍。@krokodilko这些是SQL->PL/SQL上下文切换,限制它们的需要是众所周知的。但我看到的指导是PL/SQL->SQL,即从PL/SQL块上下文开关调用SQL语句,优化效果更好,问题更少。