简体   繁体   English

插入查询的性能调优

[英]Performance Tuning for an insert query

Can someone help me in tuning this query as I am new to performance tuning in oracle. 有人可以帮助我调整此查询,因为我是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: 要调优INSERT查询,您需要以下要素:

  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. 原因: INSERT会更改数据,您需要运行不同版本的查询,直到对性能满意为止。

  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. 原因: INSERT的性能在很大程度上取决于结构和数量。

  3. Up to date statistics: Look up DBMS_STATS.GATHER_TABLE_STATS and how to use it. 最新统计信息:查找DBMS_STATS.GATHER_TABLE_STATS以及如何使用它。 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). 一种衡量性能(挂钟秒数或Oracle成本等)的方法,甚至可以更好地访问查询计划(SQL Developer:“解释计划”按钮,或者看看William的脚本)。

When I need to tune INSERT statements, I normally start with the SELECT part until I am happy with it. 当我需要调整INSERT语句时,我通常从SELECT部分开始,直到对它满意为止。 Firstly run SELECT ... , when that is fine, I run a CREATE TABLE foo NOLOGGING AS SELECT ... to measure the SELECT of all the rows. 首先运行SELECT ... ,这很好,我运行CREATE TABLE foo NOLOGGING AS SELECT ...来测量所有行的SELECT。 When thats fine, I test the whole INSERT ... SELECT ... statement. 当那没问题时,我将测试整个INSERT ... SELECT ...语句。

Any issue with performance is going to be the select , not the insert . 性能的任何问题都将是select ,而不是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) . 对于此查询,您需要两个索引: mdm_id_relation(pat_id)mdm_id_relation(pat_key) These should be a big help on performance. 这些应该对性能有很大帮助。

Note: Test the select first before doing the insert. 注意:在插入之前,先测试select

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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