Sql 插入查询的性能调整

Sql 插入查询的性能调整,sql,database,oracle,performance,Sql,Database,Oracle,Performance,有人能帮我调优这个查询吗?因为我对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

有人能帮我调优这个查询吗?因为我对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);

要优化插入查询,您将需要以下要素:

  • 用于测试查询的位置。理想情况下,一个单独的数据库,但一个单独的模式也可以。所涉及的表和索引的副本最少。原因:插入将更改数据,您需要运行不同版本的查询,直到您对性能满意为止

  • 测试表需要具有与实际表完全相同的结构,以及与实际表大致相同的数据量。原因:插件的性能在很大程度上取决于结构和数量

  • 最新统计信息:查找
    DBMS\u统计信息。收集\u表\u统计信息
    以及如何使用它。原因:让查询优化器有机会找到一个好的查询计划

  • 一种衡量性能(挂钟秒数或Oracle成本等)的方法,更好的方法是访问查询计划(SQL开发人员:解释计划按钮,或查看William的脚本)


  • 当我需要调整
    INSERT
    语句时,我通常从
    SELECT
    部分开始,直到我满意为止。首先运行
    SELECT…
    ,当一切正常时,我运行
    createtable foo NOLOGGING AS SELECT…
    来测量所有行的SELECT。好的时候,我测试整个
    INSERT。。。选择…
    语句。

    任何性能问题都将是
    选择
    ,而不是
    插入
    。我认为这是一个等价的问题:

    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
                         );
    
    对于这个查询,您需要两个索引:
    mdm\u id\u关系(pat\u id)
    mdm\u id\u关系(pat\u key)
    。这些应该对性能有很大帮助


    注意:在插入之前先测试
    选择

    为三个源表添加解释计划和表结构。您可以先将NVL(pat_id,'NULL')替换为pat_id。然后可以使用pat_id上的索引(如果有)。了解每个表中有多少行会有所帮助。有索引吗?目前需要多长时间?执行计划是什么?你能解释一下NVL(pat_id,'NULL')
    的原因吗。在表
    mdm\u id\u关系
    中是否有字符串值为
    NULL
    的值<代码>从mdm_id_关系中选择计数(*),其中pat_id='NULL'