我在 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 |
----------------------------------------------------------------------------------------------------------------