Optimize MERGE statement [message #525789] |
Wed, 05 October 2011 06:19 |
tsteinmaurer
Messages: 12 Registered: October 2008
|
Junior Member |
|
|
Hello,
I have two tables in an Oracle 10g database which should be merged on a daily base. Currently, the destination table has ~70 mio. records and the source table has ~5 mio records. The source table is some kind of staging table and gets truncated after the successful merge. The ON clause looks like that:
ON (
dst.date_year = src.date_year
and dst.date_month = src.date_month
and dst.date_day = src.date_day
and dst.datalogger_id = src.datalogger_id
and dst.device_id = src.device_id
and dst.channel_name = src.channel_name
)
In both tables, there is an compound UNIQUE constraint on the entire field set used in the ON criteria. The execution plan shows a FULL TABLE SCAN on both sides, the source and the destination table. I guess the source table is OK, because the MERGE statement needs to process the entire source table anyway, but for the destination table, the index might be helpful.
For both tables, statistics have been re-calculated by running ANALYZE TABLE xyz COMPUTE STATISTICS.
Still, a FULL TABLE SCAN on both tables.
Is this expected?
Thanks!
Thomas
|
|
|
|
|
Re: Optimize MERGE statement [message #525799 is a reply to message #525798] |
Wed, 05 October 2011 07:30 |
tsteinmaurer
Messages: 12 Registered: October 2008
|
Junior Member |
|
|
Sure:
MERGE INTO aggregates_day dst
USING (
select
date_year,
date_month,
date_day,
datalogger_id,
device_id,
channel_name,
value_count,
value_sum,
value_avg,
value_min,
value_max,
is_merged
from
aggregates_day_stage
) src
ON (
dst.date_year = src.date_year
and dst.date_month = src.date_month
and dst.date_day = src.date_day
and dst.datalogger_id = src.datalogger_id
and dst.device_id = src.device_id
and dst.channel_name = src.channel_name
)
WHEN MATCHED THEN
UPDATE SET
dst.value_count = src.value_count
, dst.value_sum = src.value_sum
, dst.value_avg = src.value_avg
, dst.value_min = src.value_min
, dst.value_max = src.value_max
, dst.updated_timestamp = sysdate
WHEN NOT MATCHED THEN
INSERT (
dst.date_year
, dst.date_month
, dst.date_day
, dst.datalogger_id
, dst.device_id
, dst.channel_name
, dst.value_count
, dst.value_sum
, dst.value_avg
, dst.value_min
, dst.value_max
, dst.aggregates_day_id
) VALUES (
src.date_year
, src.date_month
, src.date_day
, src.datalogger_id
, src.device_id
, src.channel_name
, src.value_count
, src.value_sum
, src.value_avg
, src.value_min
, src.value_max
, seq_aggregates_day_id.nextval
);
Thanks,
Thomas
|
|
|
|
|
Re: Optimize MERGE statement [message #525816 is a reply to message #525804] |
Wed, 05 October 2011 10:34 |
orsoghu
Messages: 46 Registered: May 2011 Location: Venice, Italy
|
Member |
|
|
Michel, why did you say
Quote:NEVER use ANALYZE TABLE to gather statistics.
Urgently run ANALYZE TABLE ... DELETE STATISTICS and then execute DBMS_STATS.GATHER_TABLE_STATISTICS. ?
I ask this because we inherited a framework that from time to time analyzes the tables using analyze table (oracle 10.2)
|
|
|
|
|
|
|