Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.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 交换SELECT语句时Oracle连接操作性能发生变化_Sql_Oracle_Join_Sql Execution Plan - Fatal编程技术网

Sql 交换SELECT语句时Oracle连接操作性能发生变化

Sql 交换SELECT语句时Oracle连接操作性能发生变化,sql,oracle,join,sql-execution-plan,Sql,Oracle,Join,Sql Execution Plan,在研究Oracle查询解析和性能时,我遇到了以下行为。我使用了下面的查询 SELECT 1 FROM USER_PROCEDURES WHERE OBJECT_NAME = SUBSTR( UPPER('Client_Sys.Clear_Info' ), 1, INSTR( UPPER('Client_Sys.Clear_Info'), '.' ) - 1 ) AND PROCEDURE_NAME = SUBSTR( UPPER('Client_Sys.Clear_Info' ), INS

在研究Oracle查询解析和性能时,我遇到了以下行为。我使用了下面的查询

SELECT 1 
FROM USER_PROCEDURES 
WHERE OBJECT_NAME = SUBSTR( UPPER('Client_Sys.Clear_Info' ), 1, INSTR( UPPER('Client_Sys.Clear_Info'), '.' ) - 1 ) 
AND PROCEDURE_NAME = SUBSTR( UPPER('Client_Sys.Clear_Info' ), INSTR( UPPER('Client_Sys.Clear_Info' ),'.' ) + 1 ) 
UNION 
SELECT 1 
FROM USER_OBJECTS 
WHERE OBJECT_NAME = UPPER('Client_Sys.Clear_Info') 
AND OBJECT_TYPE = 'PROCEDURE';
上述查询的解释计划如下:

现在我将查询更改为以下格式[交换SELECT语句]

SELECT 1 
FROM USER_OBJECTS 
WHERE OBJECT_NAME = UPPER('Client_Sys.Clear_Info') 
AND OBJECT_TYPE = 'PROCEDURE'
UNION 
SELECT 1 
FROM USER_PROCEDURES 
WHERE OBJECT_NAME = SUBSTR( UPPER('Client_Sys.Clear_Info' ), 1, INSTR( UPPER('Client_Sys.Clear_Info'), '.' ) - 1 ) 
AND PROCEDURE_NAME = SUBSTR( UPPER('Client_Sys.Clear_Info' ), INSTR( UPPER('Client_Sys.Clear_Info' ),'.' ) + 1 ) ; 
相应的解释方案如下:

运营成本之间存在显著差异。这可能是一件非常基本的事情,但由于我对Oracle[或任何DB东西]都是新手,这对我来说是个难题。希望你能帮我弄清楚这种行为


提前谢谢

Oracle 12c:

USER\u PROCEDURES
中的函数
NO\u ROOT\u SW\u FOR\u LOCAL
,似乎是造成差异的原因

通常,在
FROM
子句中更改谓词、表或
UNION
语句中查询块的顺序对执行计划没有任何意义。 使用
UNION
,一些子计划可能会被改变,但总成本将是相同的

对于这种特定情况,首先将语句简化为:

explain plan for select 1 from user_procedures union select 1 from dual;
select * from table(dbms_xplan.display);

explain plan for select 1 from dual union select 1 from user_procedures;
select * from table(dbms_xplan.display);
这两个次级执行计划不仅发生了切换,而且发生了重大变化,总量也有所不同。与大多数数据字典查询一样,计划很大,这里不显示266行输出

USER\u PROCEDURES
的源代码包含奇数代码
。。。从NO_ROOT_SW_获取本地(INT$DBA_过程).
。当删除本地的
无\u ROOT\u SW\u时,计划差异消失

我不知道这个函数做什么,也找不到它的任何引用。DBA_对象、DBA_源、support.oracle.com甚至Google中都没有任何内容。这是我们在没有任何严重黑客攻击的情况下所能挖掘的范围。如果成本差异是一个问题,那么您需要向Oracle提出服务请求

11g:


不是直接的答案,但我会尝试重写查询,以避免始终执行这两部分:

select 1
from   dual
where exists (
        SELECT 1 
        FROM USER_OBJECTS 
        WHERE OBJECT_NAME = UPPER('Client_Sys.Clear_Info') 
        AND OBJECT_TYPE = 'PROCEDURE') or
      exists (
        SELECT 1 
        FROM USER_PROCEDURES 
        WHERE OBJECT_NAME = SUBSTR( UPPER('Client_Sys.Clear_Info' ), 1, INSTR( UPPER('Client_Sys.Clear_Info'), '.' ) - 1 ) 
        AND PROCEDURE_NAME = SUBSTR( UPPER('Client_Sys.Clear_Info' ), INSTR( UPPER('Client_Sys.Clear_Info' ),'.' ) + 1 )); 

Oracle 11G:

在我看来,或者我到目前为止所看到的,UNION或VIEW语句处理更多的行,但开销可以忽略不计。 此外,仅仅比较计划的成本并不能为您提供最佳计划,即使它们是在同一时间启动的两个不同查询、相同的数据库和相同的设置等 它只是一个指示因素,并诱导观察者效应

当您运行这两个查询时,您是否发现执行时间有很大变化?我什么也没找到

但是如果你问为什么交换的时候成本会有差异,这是我的2美分

On plan 1, Cost was 161, CPU cost was 74M, IO Cost was 151
On plan 2, Cost was 161, CPU cost was 23M, IO Cost was 6
我发现在交换时处理选择没有什么不同,但UNION是计划不同的地方。
如上所述,成本差异是由于UNION和VIEW上额外的行处理。

请不要在执行
解释计划
语句时使用绑定变量,如
:B1
。绑定变量欺骗优化器,因为它们的值是绝对未知的。请用您将使用的示例值替换
:B1
,并获取
解释计划
输出并将其发布在此处。我已根据您的要求更新了帖子。然而解释计划的输出是类似的。有趣的问题是,查询块的顺序对计划产生影响是不寻常的。问题可能会被简化,即使使用这两个非常简单的查询,计划也会有所不同:
select1fromuser\u过程联合选择1 FROM DUAL
从双联选择1从用户程序选择1。是的。。查看用户程序的结构可能是您回答问题的原因吗。但是我很难找到您在USER_过程[11g DB]中提到的代码段。对不起,我的答案只适用于12c,11g中的代码不同。我可以在那里重现这个问题,但我不能简化代码。这可能需要一段时间才能弄清楚。对一些用户来说,执行时间不同,而对一些用户来说,执行时间不同。这主要是由于不同用户可以访问记录。所以,我认为你提到的可能是原因。我认为这是一个很好的选择。