Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.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_Sql Execution Plan - Fatal编程技术网

如何关联执行计划和SQL查询

如何关联执行计划和SQL查询,sql,oracle,sql-execution-plan,Sql,Oracle,Sql Execution Plan,这是一个问题 UPDATE hrs.rns_recon_ho c SET c.refr_numb = ( SELECT seqn_numb FROM hrs.rns_recon_ho p WHERE p.narr_1 = c.narr_1 AND p.seqn_numb = p.refr_numb AND p.prod_code = 0 ) Where c.prod_code = 0 And c.refr_numb = 0 AND c.narr_1 = '3/13/201211013198

这是一个问题

UPDATE hrs.rns_recon_ho c SET c.refr_numb = 
(
SELECT seqn_numb FROM hrs.rns_recon_ho p WHERE p.narr_1 = c.narr_1 
AND p.seqn_numb = p.refr_numb AND p.prod_code = 0
)
Where c.prod_code = 0 And c.refr_numb = 0 
AND c.narr_1 = '3/13/201211013198693442091'
这是它的执行计划

查询的哪个部分导致表访问(完整)

编辑

我的错误,我应该更清楚。现在让我澄清一下,我需要知道如何将部分执行计划与部分查询关联起来。比如说

  • 查询的哪个部分导致表访问(完整)
  • 查询的哪个部分导致表访问(通过全局索引ROWID)
  • 但是,很明显,
    索引(…)…产品代码
    是由产品代码字段引起的


    是否有任何经验法则、指导方针或技巧可以识别?或者,我们无法知道,因为优化器不会告诉我们选择某个路径的原因。

    可能会在一个表上通过提示强制进行完整表扫描,例如

    UPDATE hrs.rns_recon_ho c SET c.refr_numb =
    (
    SELECT /*+ FULL(p) */ seqn_numb FROM hrs.rns_recon_ho p WHERE p.narr_1 = c.narr_1
    AND p.seqn_numb = p.refr_numb AND p.prod_code = 0
    )
    Where c.prod_code = 0 And c.refr_numb = 0
    AND c.narr_1 = '3/13/201211013198693442091'
    

    如果您的执行计划显示两个“完全扫描”,您知道它最初是由另一个引起的。

    让我重新创建:

    CREATE TABLE RNS_RECON_HO ( PROD_CODE NUMBER,
                REFR_NUMB NUMBER,
                NARR_1 VARCHAR2 ( 25 ),
                SEQN_NUMB NUMBER primary key    );
    
    CREATE INDEX TESTTT ON RNS_RECON_HO (PROD_CODE);
    CREATE INDEX TESTTT1 ON RNS_RECON_HO (REFR_NUMB);
    CREATE INDEX TESTTT2 ON RNS_RECON_HO (NARR_1);
    
    现在复制您的计划:

    SET AUTOTRACE ON
    
    UPDATE
          RNS_RECON_HO C
    SET
          C.REFR_NUMB    =
              ( SELECT
                     SEQN_NUMB
               FROM
                    RNS_RECON_HO P
               WHERE
                        P.NARR_1 = C.NARR_1
                    AND P.SEQN_NUMB = P.REFR_NUMB
                    AND P.PROD_CODE = PROD_CODE )
    WHERE
             C.PROD_CODE = 0
          AND C.REFR_NUMB = 0
          AND C.NARR_1 = '3/13/201211013198693442091';
    
    
    0 rows updated.
    
    Execution Plan
    ----------------------------------------------------------
       0       UPDATE STATEMENT Optimizer Mode=ALL_ROWS (Cost=2 Card=1 Bytes=78)
       1    0    UPDATE RNS_RECON_HO
       2    1      TABLE ACCESS FULL RNS_RECON_HO (Cost=2 Card=1 Bytes=78)
       3    1      TABLE ACCESS BY INDEX ROWID RNS_RECON_HO (Cost=5 Card=1 Bytes=91)
       4    3        INDEX RANGE SCAN TESTTT (Cost=1 Card=1)
    
    Statistics
    ----------------------------------------------------------
            190  recursive calls
              0  spare statistic 3
              0  gcs messages sent
             25  db block gets from cache
              0  physical reads direct (lob)
              0  queue position update
              0  queue single row
              0  queue ocp pages
              0  HSC OLTP Compressed Blocks
              0  HSC IDL Compressed Blocks
              0  rows processed
    
    原因

    优化器只会选择使用比表扫描更便宜(读取次数更少)的索引。这通常意味着WHERE子句条件需要映射到索引的前导(即最左侧)列。因此,在where子句列上添加索引(PROD_CODE、REFR_NUMB、NARR_1)可以避免这种情况

    要确认,请检查此项

    CREATE INDEX TESTTT3 ON RNS_RECON_HO (PROD_CODE, REFR_NUMB, NARR_1);
    
    SET AUTOTRACE ON
    
    UPDATE
          RNS_RECON_HO C
    SET
          C.REFR_NUMB    =
              ( SELECT
                     SEQN_NUMB
               FROM
                    RNS_RECON_HO P
               WHERE
                        P.NARR_1 = C.NARR_1
                    AND P.SEQN_NUMB = P.REFR_NUMB
                    AND P.PROD_CODE = PROD_CODE )
    WHERE
             C.PROD_CODE = 0
          AND C.REFR_NUMB = 0
          AND C.NARR_1 = '3/13/201211013198693442091';
    
    0 rows updated.
    
    Execution Plan
    ----------------------------------------------------------
       0       UPDATE STATEMENT Optimizer Mode=ALL_ROWS (Cost=1 Card=1 Bytes=78)
       1    0    UPDATE RNS_RECON_HO
       2    1      INDEX RANGE SCAN TESTTT3 (Cost=1 Card=1 Bytes=78)
       3    1      TABLE ACCESS BY INDEX ROWID RNS_RECON_HO (Cost=27 Card=1 Bytes=91)
       4    3        INDEX FULL SCAN TESTTT3 (Cost=26 Card=1)
    
    Statistics
    ----------------------------------------------------------
              1  recursive calls
              0  spare statistic 3
              0  gcs messages sent
              0  db block gets from cache
              0  physical reads direct (lob)
              0  queue position update
              0  queue single row
              0  queue ocp pages
              0  HSC OLTP Compressed Blocks
              0  HSC IDL Compressed Blocks
              0  rows processed
    
    但这只是为了改变计划,但绝不承诺任何性能改进,因为您提供的投入有限

    跟进:

    外部查询正在进行FTS,因为它忽略了索引。因此,当我们放置复合键时,索引对于优化器来说是直接的,并且使用相同的索引。子查询正在使用索引,因为它与索引列上的外部查询联接


    如何确定准确的计划无法100%实现,尽管您可以通过遵循核心规则接近可能的执行计划。

    同样通过此
    更新/*+FULL(c)FULL(p)*/hrs.rns\u recon\u ho c SET c.refr\u numb=
    ?当提示是内部查询时,现在有两个完整扫描。这是否意味着外部查询正在导致
    FULL
    scan?也通过此
    UPDATE/*+FULL(p)*/hrs.rns\u recon\u ho c SET
    ?您的主键是什么?你有什么索引?你有分区吗?@realspirituals
    seqn\u numb
    是PK,所有查询的字段都被索引,表是分区的。你能发布你的创建表、索引脚本吗?或者在sqlfiddle.comBy中设置它。顺便说一句,我注意到您正在加入
    seqn\u numb=refr\u numb
    并更新相同的,即
    refr\u numb=seqn\u numb
    。你想干什么。完整表扫描将被加入
    CREATE INDEX TESTTT3 ON RNS_RECON_HO (PROD_CODE, REFR_NUMB, NARR_1);
    
    SET AUTOTRACE ON
    
    UPDATE
          RNS_RECON_HO C
    SET
          C.REFR_NUMB    =
              ( SELECT
                     SEQN_NUMB
               FROM
                    RNS_RECON_HO P
               WHERE
                        P.NARR_1 = C.NARR_1
                    AND P.SEQN_NUMB = P.REFR_NUMB
                    AND P.PROD_CODE = PROD_CODE )
    WHERE
             C.PROD_CODE = 0
          AND C.REFR_NUMB = 0
          AND C.NARR_1 = '3/13/201211013198693442091';
    
    0 rows updated.
    
    Execution Plan
    ----------------------------------------------------------
       0       UPDATE STATEMENT Optimizer Mode=ALL_ROWS (Cost=1 Card=1 Bytes=78)
       1    0    UPDATE RNS_RECON_HO
       2    1      INDEX RANGE SCAN TESTTT3 (Cost=1 Card=1 Bytes=78)
       3    1      TABLE ACCESS BY INDEX ROWID RNS_RECON_HO (Cost=27 Card=1 Bytes=91)
       4    3        INDEX FULL SCAN TESTTT3 (Cost=26 Card=1)
    
    Statistics
    ----------------------------------------------------------
              1  recursive calls
              0  spare statistic 3
              0  gcs messages sent
              0  db block gets from cache
              0  physical reads direct (lob)
              0  queue position update
              0  queue single row
              0  queue ocp pages
              0  HSC OLTP Compressed Blocks
              0  HSC IDL Compressed Blocks
              0  rows processed