Oracle - 未使用大表上的索引

标签 oracle performance indexing

我有两个表 MP_LM 和 MP_BS,这两个表如下所示连接到一个 View 并在 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。

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 上的这个索引如何帮助提高性能。

最佳答案

至少有两个原因:

  1. INDEX FAST FULL SCAN 而不是 TABLE ACCESS FULL 即,它不是对表进行全面扫描,而是对索引进行全面扫描,这可能更小然后对应表
  2. UNION 要求删除重复的行,这在计划中由 union all 后跟 sort unique 表示。当使用索引时,使用索引返回的数据已经排序,因此可以在性能上获得另一个好处。

关于Oracle - 未使用大表上的索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29220798/

相关文章:

.net - 实体数据模型向导中没有Oracle DataSource

java - 从 Java 字符串中删除字符 e280a8

java - 测量 Java 中对象创建的性能

JavaScript setInterval() 性能

sql-server - SQL Server 非聚集索引

mysql - 如果使用 where 条件更改了列的数据类型,如何查找列的记录

oracle - 您如何判断 ALL_TAB_COLS 中哪些列未使用?

python - 将多个 csv 加载到数据框中的最快方法

javascript - 使 str.index() 只匹配整个单词

Objective-C 提取 rangeOfString : 返回的范围的索引