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查询的好链接?
提前致谢。
答案 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如果/何时发生)。