我有两个表MP_LM和MP_BS,这两个表如下所示连接到一个视图并在select语句中使用。
CREATE VIEW MV_MP_LM_V (MP_ID,ID,PID,NAME,IS_D) AS
SELECT C.mp_ID,C.BS_ID ID,NULL PID,C.BS_NM NAME,'Y' IS_D FROM MP_BS C UNION
SELECT CM.mp_ID,CM.LM_ID ID,CM.IT_ID PID,CM.LM_NM NAME,CM.IS_D FROM MP_LC_REF_ORIG CM WHERE FLG = 'Y' ;
表MP_BS的PK如下所示。
ALTER TABLE MP_BS ADD CONSTRAINT MP_BS_PK PRIMARY KEY (MP_ID, BS_ID, BS_NM);
以下是我正在运行的选择。
SELECT DISTINCT
ID,
PID,
NAME,
DECODE (pid,
NULL, DECODE (id, -1, NULL, id || '$'),
pid || '$' || id)
tree_id,
DECODE (ID, -1, 0, 1) s1
FROM MV_MP_LM_V, TABLE (MV_SPLITARR5 (336700164 , ',', '$')) c
WHERE mp_ID = c.id1
AND IS_D= 'Y'
AND ID <> -1
AND ( 0 = 0
OR ( 0 > 0
))
ORDER BY s1, DECODE (pid, NULL, 0, 1), name;
对于上面的选择,没有索引MP_BS_PK,选择花费35秒,下面是计划..
Plan hash value: 2313865915
-------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 206M| 123G| | 56M (1)|188:17:27 |
| 1 | SORT ORDER BY | | 206M| 123G| 131G| 56M (1)|188:17:27 |
| 2 | HASH UNIQUE | | 206M| 123G| 131G| 28M (1)| 94:49:48 |
|* 3 | HASH JOIN | | 206M| 123G| | 410K (1)| 01:22:09 |
| 4 | COLLECTION ITERATOR PICKLER FETCH| MV_SPLITARR5 | 8168 | 16336 | | 29 (0)| 00:00:01 |
| 5 | VIEW | MV_MP_LM_V | 2529K| 1546M| | 409K (1)| 01:21:56 |
| 6 | SORT UNIQUE | | 2529K| 1489M| 1572M| 409K (1)| 01:21:56 |
| 7 | UNION-ALL | | | | | | |
|* 8 | TABLE ACCESS FULL | MP_BS | 121K| 2964K| | 377 (1)| 00:00:05 |
|* 9 | TABLE ACCESS FULL | MP_LM_REF_ORIG | 2408K| 1486M| | 79820 (1)| 00:15:58 |
-------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("MP_ID"=TO_NUMBER(SYS_OP_ATG(VALUE(KOKBF$),1,2,2)))
8 - filter("C"."BS_ID"<>(-1))
9 - filter("CM"."LM_ID"<>(-1) AND "FLG"='Y' AND "CM"."IS_D"='Y')
Note
-----
- dynamic sampling used for this statement (level=2)
使用pk,选择时间为10秒,以下是此计划。
Plan hash value: 2486203413
-----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | 1929 | 26028 (1)| 00:05:13 |
| 1 | SORT ORDER BY | | | 1929 | 26028 (1)| 00:05:13 |
| 2 | HASH UNIQUE | | | 1929 | 26027 (1)| 00:05:13 |
|* 3 | HASH JOIN | | 3 | 1929 | 26026 (1)| 00:05:13 |
| 4 | VIEW | MV_MP_LM_V | 10 | 6410 | 25997 (1)| 00:05:12 |
| 5 | SORT UNIQUE | | | | | |
| 6 | UNION-ALL | | | | | |
|* 7 | INDEX FAST FULL SCAN | MP_BS_PK | 121K| 2964K| 192 (1)| 00:00:03 |
|* 8 | TABLE ACCESS FULL | MP_LM_REF_ORIG | 2408K| 1486M| 79820 (1)| 00:15:58 |
| 9 | COLLECTION ITERATOR PICKLER FETCH| MV_SPLITARR5 | 8168 | 16336 | 29 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("MP_ID"=TO_NUMBER(SYS_OP_ATG(VALUE(KOKBF$),1,2,2)))
7 - filter("C"."BS_ID"<>(-1))
8 - filter("CM"."LM_ID"<>(-1) AND "FLG"='Y' AND "CM"."IS_D"='Y')
Note
-----
- dynamic sampling used for this statement (level=2)
我研究了很多东西,但无法找出为什么较小的表上的pk / index会提供更快的性能。
没有。每个表中的行是:
MP_LM_REF_ORIG :- 10241670
MP_BS :- 147575
我尝试在id MP_ID上创建表MP_LM_REF_ORIG上的索引,但不使用该索引。
有人可以解释一下MP_BS上的这个索引如何帮助提高性能。
答案 0 :(得分:0)
至少有两个原因:
INDEX FAST FULL SCAN
代替TABLE ACCESS FULL
,即不是对表格进行全面扫描,而是对索引使用全扫描,这可能比对应的表格小一些UNION
要求删除重复的行,这在计划中由union all
后跟sort unique
表示。使用索引时,使用索引返回的数据已经排序,因此这可能是性能的另一个增益。