如何关联执行计划和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'
这是它的执行计划
查询的哪个部分导致表访问(完整)
编辑
我的错误,我应该更清楚。现在让我澄清一下,我需要知道如何将部分执行计划与部分查询关联起来。比如说
索引(…)…产品代码
是由产品代码字段引起的
是否有任何经验法则、指导方针或技巧可以识别?或者,我们无法知道,因为优化器不会告诉我们选择某个路径的原因。可能会在一个表上通过提示强制进行完整表扫描,例如
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
?您的主键是什么?你有什么索引?你有分区吗?@realspiritualsseqn\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