Sql 解码。并且假设驱动表应该是DISB_A(从DISB_B驱动查询要容易得多,所以让我们知道针对DISB_B的独立过滤器是否能有效地减少访问的行数)。我会将查询重写为(可能有拼写错误):
并创建以下索引:Sql 解码。并且假设驱动表应该是DISB_A(从DISB_B驱动查询要容易得多,所以让我们知道针对DISB_B的独立过滤器是否能有效地减少访问的行数)。我会将查询重写为(可能有拼写错误):,sql,oracle,query-optimization,Sql,Oracle,Query Optimization,并创建以下索引: create index DISB_A_idx_v on DISB_A (v_id, effdate); create index DISB_A_idx_code on DISB_A (code, effdate); create index DISB_B_idx on DISB_B (nd_id,a_id,dsba_id); 如果这仍然是相对缓慢的,那么它将有助于有一些反馈如何选择这些过滤器真的是。看看如何在计划内获取行源代码执行统计信息(的第4点),并将该信息包含在原始问
create index DISB_A_idx_v on DISB_A (v_id, effdate);
create index DISB_A_idx_code on DISB_A (code, effdate);
create index DISB_B_idx on DISB_B (nd_id,a_id,dsba_id);
如果这仍然是相对缓慢的,那么它将有助于有一些反馈如何选择这些过滤器真的是。看看如何在计划内获取行源代码执行统计信息(的第4点),并将该信息包含在原始问题中。您之前问了基本相同的问题(),答案建议使用两个索引,这两个索引都不在本表中。我建议你删除这个问题,直到你尝试这个问题的答案。你可以看到,我已经在问题本身添加了索引。我还包括了CREATEINDEX语句。我没有看到前两列是
nd\u id
和a\u id
的索引。同样,对于第二个推荐索引,您不认为我不需要为disb_b表添加索引,因为成本/索引利用率在那里是正确的。根据我的说法(我可能错了),问题在于解散一张桌子。因此,不应该将重点放在表A中的索引而不是表B中的索引?成本是使用您的查询、统计和优化器数学进行的估计。它有时最终将无法代表现实。xxxxxxxx
是什么意思?根据您的计划谓词判断,您在这里输入了一个文本值,这使得您的解码无法索引-您应该考虑重写它(对于优化器来说,解码也很难估计)。如果基数估计值是合理的(并且表DISB_a
中只有少量的行与谓词匹配),那么通过重写,可以正确使用索引,从而大大提高性能。这实际上首先会复制记录。上面写的逻辑和解码不一样。Decode将选择v_id(如果匹配)或状态代码(如果完整)。但是我们在上面的解决方案中从这两个条件中获取记录。我不这么认为,如果v_id匹配(隐式要求两者都不为null),则第一部分将成功,如果v_id为null且输入为null,则第二部分将成功,如果代码完整且v_id与输入不匹配(或者如果只有一个为null)。您是否有导致双重计数的示例输入和数据?
INDEX_OWNER INDEX_NAME TABLE_OWNER TABLE_NAME COLUMN_NAME COLUMN_POSITION COLUMN_LENGTH CHAR_LENGTH DESCEND COLLATED_COLUMN_ID
-------------------------------------------------------------------------------------------------------------------------------------
DEVL DISB_B_INDX1 DEVL DISB_B DSBA_ID 1 22 0 ASC
DEVL DISB_B_INDX1 DEVL DISB_B SEQNBR 2 22 0 ASC
DEVL DISB_B_PRIME DEVL DISB_B DSBA_ID 1 22 0 ASC
DEVL DISB_B_PRIME DEVL DISB_B ND_ID 2 22 0 ASC
DEVL DISB_B_PRIME DEVL DISB_B A_ID 3 13 13 ASC
DEVL DISB_B_PRIME DEVL DISB_B DIO_ID 4 6 6 ASC
DEVL DISB_B_PRIME DEVL DISB_B AIO_QUAL 5 22 0 ASC
DEVL DISB_B_PRIME DEVL DISB_B DMT_CODE 6 3 3 ASC
DEVL DISB_B_PRIME DEVL DISB_B DMT_SEQNBR 7 22 0 ASC
DEVL DISB_B_PRIME DEVL DISB_B ORDER_SEQNBR 8 22 0 ASC
DEVL DISB_B_PRIME DEVL DISB_B NBR 9 20 20 ASC
SQL> explain plan
for
SELECT SUM ( NVL ( dd.req_amt , 0 ) )
FROM DISB_A db ,
DISB_B dd
WHERE db.id = dd.dsba_id
AND dd.nd_id = xxxxxxxx
AND dd.a_id = 'xx-xx'
AND DECODE (db.v_id , xxxxxxxxx , 'COMPLETE' , db.code ) = 'COMPLETE'
AND db.effdate BETWEEN TRUNC ( SYSDATE , 'YEAR' ) AND SYSDATE;
Explained.
Elapsed: 00:00:00.04
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
Plan hash value: 4272128008
--------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 58 | 62271 (1)| 00:00:03 |
| 1 | SORT AGGREGATE | | 1 | 58 | | |
|* 2 | FILTER | | | | | |
| 3 | NESTED LOOPS | | 1 | 58 | 62271 (1)| 00:00:03 |
| 4 | NESTED LOOPS | | 10 | 58 | 62271 (1)| 00:00:03 |
|* 5 | TABLE ACCESS STORAGE FULL | DISB_A | 10 | 300 | 62231 (1)| 00:00:03 |
|* 6 | INDEX RANGE SCAN | DISB_B_PRIME | 1 | | 3 (0)| 00:00:01 |
| 7 | TABLE ACCESS BY INDEX ROWID| DISB_B | 1 | 28 | 4 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(SYSDATE@!>=TRUNC(SYSDATE@!,'fmyear'))
5 - storage(DECODE("DB"."EV_ID",1263421688,'COMPLETE',"DB"."STATUS_CODE")='COMPLETE'
AND "DB"."EFFDATE">=TRUNC(SYSDATE@!,'fmyear') AND "DB"."EFFDATE"<=SYSDATE@!)
filter(DECODE("DB"."EV_ID",1263421688,'COMPLETE',"DB"."STATUS_CODE")='COMPLETE'
AND "DB"."EFFDATE">=TRUNC(SYSDATE@!,'fmyear') AND "DB"."EFFDATE"<=SYSDATE@!)
6 - access("DB"."ID"="DD"."DSBA_ID" AND "DD"."IND_ID"=20972265 AND
"DD"."GA_ID"='150563-01')
25 rows selected.
Elapsed: 00:00:00.02
SQL> SELECT SUM ( NVL ( dd.req_amt , 0 ) )
FROM DISB_A db ,
DISB_B dd
WHERE db.id = dd.dsba_id
AND dd.nd_id = xxxxxxxx
AND dd.a_id = 'xx-xx'
AND DECODE (db.v_id , xxxxxxxxx , 'COMPLETE' , db.code ) = 'COMPLETE'
AND db.effdate BETWEEN TRUNC ( SYSDATE , 'YEAR' ) AND SYSDATE;
SUM(NVL(DD.REQ_AMT,0))
______________________
62500
**1 row selected.
Elapsed: 00:00:01.65**
**CREATE INDEX DISB_A_INDX5 ON DISB_A (ID,IND_id,EV_ID,status_code,EFFDATE ASC) NOPARALLEL;**
PLAN_TABLE_OUTPUT
Plan hash value: 2535999045
-----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 58 | 18669 (1)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 58 | | |
|* 2 | FILTER | | | | | |
| 3 | NESTED LOOPS | | 1 | 58 | 18669 (1)| 00:00:01 |
| 4 | NESTED LOOPS | | 35 | 58 | 18669 (1)| 00:00:01 |
|* 5 | INDEX STORAGE FAST FULL SCAN| DISB_A_INDX5 | 35 | 1050 | 18598 (1)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | DISB_B_PRIME | 1 | | 3 (0)| 00:00:01 |
| 7 | TABLE ACCESS BY INDEX ROWID | DISB_B | 1 | 28 | 4 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(SYSDATE@!>=TRUNC(SYSDATE@!,'fmyear'))
5 - storage(DECODE("DB"."EV_ID",1263421688,'COMPLETE',"DB"."STATUS_CODE")='COMPLETE' AND
"DB"."EFFDATE"<=SYSDATE@! AND "DB"."EFFDATE">=TRUNC(SYSDATE@!,'fmyear'))
filter(DECODE("DB"."EV_ID",1263421688,'COMPLETE',"DB"."STATUS_CODE")='COMPLETE' AND
"DB"."EFFDATE"<=SYSDATE@! AND "DB"."EFFDATE">=TRUNC(SYSDATE@!,'fmyear'))
6 - access("DB"."ID"="DD"."DSBA_ID" AND "DD"."IND_ID"=20972265 AND
"DD"."GA_ID"='150563-01')
25 rows selected.
Elapsed: 00:00:00.03
SQL> SELECT SUM ( NVL ( dd.req_amt , 0 ) )
FROM DISB_A db ,
DISB_B dd
WHERE db.id = dd.dsba_id
AND dd.nd_id = xxxxxxxx
AND dd.a_id = 'xx-xx'
AND DECODE (db.v_id , xxxxxxxxx , 'COMPLETE' , db.code ) = 'COMPLETE'
AND db.effdate BETWEEN TRUNC ( SYSDATE , 'YEAR' ) AND SYSDATE;
SUM(NVL(DD.REQ_AMT,0))
______________________
62500
**1 row selected.
Elapsed: 00:00:05.45**
select sum(req_amt)
from (
SELECT SUM ( dd.req_amt ) req_amt
FROM DISB_A db ,
DISB_B dd
WHERE db.id = dd.dsba_id
AND dd.nd_id = :xxxxxxxx
AND dd.a_id = 'xx-xx'
AND db.effdate BETWEEN TRUNC ( SYSDATE , 'YEAR' ) AND SYSDATE
and db.v_id = :xxxxxxxxx
union all
SELECT SUM ( dd.req_amt ) req_amt
FROM DISB_A db ,
DISB_B dd
WHERE db.id = dd.dsba_id
AND dd.nd_id = :xxxxxxxx
AND dd.a_id = 'xx-xx'
AND db.effdate BETWEEN TRUNC ( SYSDATE , 'YEAR' ) AND SYSDATE
and (db.v_id is null and :xxxxxxxxx is null)
union all
SELECT SUM ( dd.req_amt ) req_amt
FROM DISB_A db ,
DISB_B dd
WHERE db.id = dd.dsba_id
AND dd.nd_id = :xxxxxxxx
AND dd.a_id = 'xx-xx'
AND db.effdate BETWEEN TRUNC ( SYSDATE , 'YEAR' ) AND SYSDATE
and db.code = 'COMPLETE'
and lnnvl(db.v_id = :xxxxxxxxx )
)
create index DISB_A_idx_v on DISB_A (v_id, effdate);
create index DISB_A_idx_code on DISB_A (code, effdate);
create index DISB_B_idx on DISB_B (nd_id,a_id,dsba_id);