简体   繁体   中英

Performance Tuning for an insert query

Can someone help me in tuning this query as I am new to performance tuning in oracle.

INSERT INTO mdm_id_relation
    SELECT 
        pat_key, hub_pat_id, msa_pat_id, pat_id
    FROM 
        ods_raw_patient_mdm_process p1
    WHERE NVL (pat_id, 'NULL') IN (SELECT pat_id
                                   FROM mdm_id_relation)
      AND NOT EXISTS (SELECT pat_key
                      FROM mdm_id_relation p2
                      WHERE p1.pat_key = p2.pat_key);

To tune an INSERT query, you'll need the follwowing ingredients:

  1. A place to test your query. Ideally a separate database, but a separate schema might do as well. Minimally a copy of the tables and indexes that are involved. Reason: the INSERT will change data, you'll need to run different versions of the query until you are happy with the performance.

  2. The test tables need to have exactly the same structure as the real table and roughly the same amount of data as the real thing. Reason: The performance of the INSERT depends heavily on both structure and amount.

  3. Up to date statistics: Look up DBMS_STATS.GATHER_TABLE_STATS and how to use it. Reason: Give the query optimizer a chance to find a good query plan.

  4. A way to measure performance (wall clock seconds or Oracle costs etc.), and, even better, access to the query plan (SQL Developer: Explain Plan button, or have a look at William's script).

When I need to tune INSERT statements, I normally start with the SELECT part until I am happy with it. Firstly run SELECT ... , when that is fine, I run a CREATE TABLE foo NOLOGGING AS SELECT ... to measure the SELECT of all the rows. When thats fine, I test the whole INSERT ... SELECT ... statement.

Any issue with performance is going to be the select , not the insert . I think this is an equivalent query:

INSERT INTO mdm_id_relation (pat_key, hub_pat_id, msa_pat_id, pat_id) -- always list the columns!
    SELECT pat_key, hub_pat_id, msa_pat_id, pat_id
    FROM ods_raw_patient_mdm_process p1
    WHERE EXISTS (SELECT 1
                  FROM mdm_id_relation mir
                  WHERE mir.pat_id = p1.pat_id
                 ) AND
          NOT EXISTS (SELECT 1
                      FROM mdm_id_relation mir
                      WHERE p1.pat_key = mir.pat_key
                     );

For this query, you want two indexes: mdm_id_relation(pat_id) and mdm_id_relation(pat_key) . These should be a big help on performance.

Note: Test the select first before doing the insert.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM