1

ORACLEにSELECTステートメントがあります。

SELECT COUNT(DISTINCT ds1.endpoint_msisdn)                  multiple30,
       dss1.service,
       dss1.endpoint_provisioning_id,
       dss1.company_scope,
       Nvl(x.subscription_status, dss1.subscription_status) subscription_status
FROM   daily_summary ds1
       join daily_summary ds2
         ON ds1.endpoint_msisdn = ds2.endpoint_msisdn,
       daily_summary_static dss1,
       daily_summary_static dss2,
       (SELECT NULL subscription_status
        FROM   dual
        UNION ALL
        SELECT -2 subscription_status
        FROM   dual) x
WHERE  ds1.summary_ts >= To_date('10-04-2012', 'dd-mm-yyyy') - 30
       AND ds1.summary_ts <= To_date('10-04-2012', 'dd-mm-yyyy')
       AND dss1.last_active >= To_date('10-04-2012', 'dd-mm-yyyy') - 30
       AND dss1.last_active <= To_date('10-04-2012', 'dd-mm-yyyy')
       AND dss2.last_active >= To_date('10-04-2012', 'dd-mm-yyyy') - 30
       AND dss2.last_active <= To_date('10-04-2012', 'dd-mm-yyyy')
       AND dss1.service <> dss2.service
       AND ( dss1.company_scope = 2
              OR dss1.company_scope = 5 )
       AND ( dss2.company_scope = 2
              OR dss2.company_scope = 5 )
       AND dss1.company_scope = dss2.company_scope
       AND ds1.endpoint_noc_id = dss1.endpoint_noc_id
       AND ds1.endpoint_host_id = dss1.endpoint_host_id
       AND ds1.endpoint_instance_id = dss1.endpoint_instance_id
       AND ds2.endpoint_noc_id = dss2.endpoint_noc_id
       AND ds2.endpoint_host_id = dss2.endpoint_host_id
       AND ds2.endpoint_instance_id = dss2.endpoint_instance_id
       AND dss1.endpoint_provisioning_id = dss2.endpoint_provisioning_id
       AND Least(1, ds1.total_actions) = 1
       AND Least(1, ds2.total_actions) = 1
GROUP  BY dss1.service,
          dss1.endpoint_provisioning_id,
          dss1.company_scope,
          Nvl(x.subscription_status, dss1.subscription_status); 

このクエリが私の環境に戻るまでに約26分かかりましたが、セクションを削除すると次のようになります。

dss1.last_active >= to_date('10-04-2012','dd-mm-yyyy') - 30 AND
                   dss1.last_active <= to_date('10-04-2012','dd-mm-yyyy') AND
                    dss2.last_active >= to_date('10-04-2012','dd-mm-yyyy') - 30 AND
                   dss2.last_active <= to_date('10-04-2012','dd-mm-yyyy') AND

実行には20秒しかかかりませんでした。

last_active列にインデックスがありますが、このセクションのパフォーマンスが大幅に低下する理由がわかりません。何か案は?


これを実行すると、非常に高速でした。

select * from daily_summary_static where last_active >= to_date('10-04-2012','dd-mm-yyyy') - 30 AND last_active <= to_date('10-04-2012','dd-mm-yyyy');


ステートメントの計画を説明してください。ここでは全表スキャンが表示されません。なぜ実行が遅いのかわかりません。

----------------------------------------------------------------------------------------------------------------
| Id  | Operation                               | Name                 | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                        |                      |     1 |   119 |   204   (3)| 00:00:03 |
|   1 |  SORT GROUP BY                          |                      |     1 |   119 |   204   (3)| 00:00:03 |
|   2 |   MERGE JOIN CARTESIAN                  |                      |     1 |   119 |   203   (2)| 00:00:03 |
|*  3 |    TABLE ACCESS BY INDEX ROWID          | DAILY_SUMMARY        |     1 |    27 |    11   (0)| 00:00:01 |
|   4 |     NESTED LOOPS                        |                      |     1 |   116 |   199   (3)| 00:00:03 |
|*  5 |      HASH JOIN                          |                      |     3 |   267 |   178   (3)| 00:00:03 |
|*  6 |       HASH JOIN                         |                      |     1 |    65 |   140   (2)| 00:00:02 |
|   7 |        TABLE ACCESS BY INDEX ROWID      | DAILY_SUMMARY_STATIC |    61 |  1647 |    37   (3)| 00:00:01 |
|   8 |         BITMAP CONVERSION TO ROWIDS     |                      |       |       |            |          |
|   9 |          BITMAP AND                     |                      |       |       |            |          |
|  10 |           BITMAP CONVERSION FROM ROWIDS |                      |       |       |            |          |
|  11 |            SORT ORDER BY                |                      |       |       |            |          |
|* 12 |             INDEX RANGE SCAN            | DSS_LAST_ACTIVE      |   560 |       |     3   (0)| 00:00:01 |
|  13 |           BITMAP OR                     |                      |       |       |            |          |
|  14 |            BITMAP CONVERSION FROM ROWIDS|                      |       |       |            |          |
|* 15 |             INDEX RANGE SCAN            | DSS_C_SCOPE_IDX      |   560 |       |    18   (0)| 00:00:01 |
|  16 |            BITMAP CONVERSION FROM ROWIDS|                      |       |       |            |          |
|* 17 |             INDEX RANGE SCAN            | DSS_C_SCOPE_IDX      |   560 |       |     1   (0)| 00:00:01 |
|  18 |        TABLE ACCESS BY INDEX ROWID      | DAILY_SUMMARY        |  1773 | 67374 |   102   (0)| 00:00:02 |
|* 19 |         INDEX RANGE SCAN                | DS_DAILY_ACTIVE_IDX  |  1767 |       |    14   (0)| 00:00:01 |
|  20 |       TABLE ACCESS BY INDEX ROWID       | DAILY_SUMMARY_STATIC |    61 |  1464 |    37   (3)| 00:00:01 |
|  21 |        BITMAP CONVERSION TO ROWIDS      |                      |       |       |            |          |
|  22 |         BITMAP AND                      |                      |       |       |            |          |
|  23 |          BITMAP CONVERSION FROM ROWIDS  |                      |       |       |            |          |
|  24 |           SORT ORDER BY                 |                      |       |       |            |          |
|* 25 |            INDEX RANGE SCAN             | DSS_LAST_ACTIVE      |   560 |       |     3   (0)| 00:00:01 |
|  26 |          BITMAP OR                      |                      |       |       |            |          |
|  27 |           BITMAP CONVERSION FROM ROWIDS |                      |       |       |            |          |
|* 28 |            INDEX RANGE SCAN             | DSS_C_SCOPE_IDX      |   560 |       |    18   (0)| 00:00:01 |
|  29 |           BITMAP CONVERSION FROM ROWIDS |                      |       |       |            |          |
|* 30 |            INDEX RANGE SCAN             | DSS_C_SCOPE_IDX      |   560 |       |     1   (0)| 00:00:01 |
|* 31 |      INDEX RANGE SCAN                   | DS_PKEY              |     8 |       |     2   (0)| 00:00:01 |
|  32 |    BUFFER SORT                          |                      |     2 |     6 |   193   (3)| 00:00:03 |
|  33 |     VIEW                                |                      |     2 |     6 |     4   (0)| 00:00:01 |
|  34 |      UNION-ALL                          |                      |       |       |            |          |
|  35 |       FAST DUAL                         |                      |     1 |       |     2   (0)| 00:00:01 |
|  36 |       FAST DUAL                         |                      |     1 |       |     2   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------------
4

1 に答える 1

2

このセクションは実際にそれを遅くするので:

AND dss1.last_active >= To_date('10-04-2012', 'dd-mm-yyyy') - 30
AND dss1.last_active <= To_date('10-04-2012', 'dd-mm-yyyy')
AND dss2.last_active >= To_date('10-04-2012', 'dd-mm-yyyy') - 30
AND dss2.last_active <= To_date('10-04-2012', 'dd-mm-yyyy')

last_activeインデックスonは、使用すべきでないときに使用されているように思われます。つまり、別のより有用なインデックスを使用できなくなります。私の賭けは、dss1とdss2を結合するために使用される別のインデックスにありますが、実際には問題ではありません。

したがって、クエリオプティマイザがインデックスを使用できなくなるように、このように意図的にブロックを変更して、インデックスの使用を無効にすることを提案します。

AND (dss1.last_active+0) >= To_date('10-04-2012', 'dd-mm-yyyy') - 30
AND (dss1.last_active+0) <= To_date('10-04-2012', 'dd-mm-yyyy')
AND (dss2.last_active+0) >= To_date('10-04-2012', 'dd-mm-yyyy') - 30
AND (dss2.last_active+0) <= To_date('10-04-2012', 'dd-mm-yyyy')
于 2012-04-13T06:55:52.297 に答える