调整和性能

时间:2014-06-02 22:06:09

标签: sql performance oracle

INSERT INTO <TABLED>
SELECT A.* FROM 
<TABLEA> A  WHERE A.MED_DTL_STATUS='0' 
AND A.TRANS_ID
NOT IN 
(      
  SELECT DISTINCT TRANS_ID_X_REF FROM <TABLEB>
  UNION 
  SELECT DISTINCT TRANS_ID FROM <TABLEA> WHERE ADJUSTMENT_TYPE='3' 
);

该表有超过250列。 Select语句将返回超过300000条记录。上面的查询运行了很长时间。我从未参与过性能调优。有人可以帮我调优一下,或者给我一些关于如何调优oracle查询的好链接?

提前致谢。

3 个答案:

答案 0 :(得分:1)

我发现NOT IN子句真的很慢。我会用NOT EXISTS重写查询。

INSERT INTO <TABLED>
SELECT A.* FROM <TABLEA> A  
WHERE A.MED_DTL_STATUS='0' 
AND NOT EXISTS (
    SELECT B.TRANS_ID_X_REF 
    FROM <TABLEB> B 
    WHERE B.TRANS_ID_X_REF = A.TRANS_ID
)
AND NOT EXISTS (
    SELECT A2.TRANS_ID 
    FROM <TABLEA> A2 
    WHERE A2.TRANS_ID = A.TRANS_ID
    AND A2.ADJUSTMENT_TYPE='3'
);

上面的查询假设TableA和TableB上的TRANS_ID上有索引。这可能无法真正解决您的问题,但如果不了解数据模型和索引,则可能值得一试。

答案 1 :(得分:0)

除了已经给出的好建议之外,无论何时将大量记录插入表中,最好删除该表上的索引。 INSERT进程完成后,重新创建索引。

答案 2 :(得分:0)

这个谓词的选择性如何?

A.MED_DTL_STATUS='0'

如果它过滤掉表中的大部分行,那么在MED_DTL_STATUS上创建索引可能会有所帮助。

请注意,对于IN,Oracle已经(或者至少曾经有)约1000个项目的限制:如果您的子查询开始返回的行数多于您将获得错误的行数(可以使用左外部联接重写此IN如果/何时发生)。