Ich habe eine SELECT-Anweisung in ORACLE:Wie kann ich die SELECT-Anweisung optimieren, die auf einer Oracle-Datenbank ausgeführt wird?
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);
Diese Abfrage etwa 26 Minuten in Anspruch nahm in meiner Umgebung zurückzukehren, aber wenn ich den Abschnitt zu entfernen:
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
es dauerte nur 20 Sekunden laufen .
Wir haben Index auf die Spalte last_active, ich weiß nicht, warum der Abschnitt die Leistung so sehr verlangsamen? irgendwelche Ideen?
Wenn ich das ausführen, war es sehr schnell.
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');
Erklären Plan für die Anweisung, ich habe keine vollständige Tabelle finden Sie hier scannen, weiß nicht, warum es so langsam laufen:
----------------------------------------------------------------------------------------------------------------
| 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 |
----------------------------------------------------------------------------------------------------------------
Es ist immer noch sehr lange dauern, wenn ich das entfernen ** - 30 ** Bedingung. was verwirrt mich ist, warum die datum manipulation auf dss war so langsam, aber es war schnell, wenn bei der datum manipulation auf ds.? da die datensätze in ds weit mehr waren als dss ... und wir haben index auf last_active in dss. –
In diesen Zeilen gibt es keine intensive Datumsmanipulation, da die Werte, mit denen Sie 'last_active' vergleichen, statisch sind und nur einmal berechnet werden. Sie sagen, Sie haben einen Index, aber sind Sie sicher, dass der Optimizer ihn verwendet? Können Sie die Ausführungspläne für beide Fälle hinzufügen? –
Hallo Erkan, der EXPLAIN-Plan wurde im ursprünglichen Beitrag hinzugefügt, diese Erklärung ist für die "langsame" SELECT-Anweisung, ich sehe hier keinen vollständigen Tabellenscan, der Indexbereich-Scan ist auf dem Index passiert ** DSS_LAST_ACTIVE **, don Warum läuft es so langsam? –