如何调整不在查询中
How to tune not in query
请调整我的 query.It 执行时间为 17 秒
SELECT grirno, grirdate
FROM grirmain
WHERE grirno NOT IN
(SELECT grirno
FROM grir_pass
WHERE ins_check IS NOT NULL AND grirdate > '01-apr-2013')
AND grirno IS NOT NULL
AND chkuser IS NOT NULL
AND grirdate > '01-apr-2013'
ORDER BY TO_NUMBER (SUBSTR (GRIRNO,INSTR (GRIRNO,'/',1,1)+ 1,( INSTR (GRIRNO,'/',1,2)- INSTR (GRIRNO,'/',1,1)- 1))) DESC
您的子查询实际上似乎与外部查询完全非相关。因此,Oracle 很可能会执行一次并缓存结果以备后用。我可以建议以下索引:
CREATE INDEX idx ON grirmain (gridate, girano, chksuer);
这个索引至少应该让Oracle能够快速处理WHERE
子句,而且它覆盖了SELECT
子句中的两列。如前所述,不相关的子查询应该执行一次然后缓存。
至于 ORDER BY
子句,索引可能无济于事,Oracle 将不得不手动排序。
我建议使用 NOT EXISTS
:
来写这篇文章
SELECT m.grirno, m.grirdate
FROM grirmain m
WHERE NOT EXISTS (SELECT 1
FROM grir_pass p
WHERE g.grirno = p.grirno AND
p.ins_check IS NOT NULL AND
p.grirdate > DATE '2018-04-01'
) AND
m.grirno IS NOT NULL AND
m.chkuser IS NOT NULL AND
m.grirdate > DATE '2018-04-01'
ORDER BY TO_NUMBER(SUBSTR (GRIRNO,INSTR (GRIRNO,'/',1,1)+ 1,( INSTR (GRIRNO,'/',1,2)- INSTR (GRIRNO,'/',1,1)- 1))) DESC;
然后,您需要 grir_pass(grirno, grirdate, ins_check)
和 grirmain(grirno, grirdate, chkuser)
上的索引。
请调整我的 query.It 执行时间为 17 秒
SELECT grirno, grirdate
FROM grirmain
WHERE grirno NOT IN
(SELECT grirno
FROM grir_pass
WHERE ins_check IS NOT NULL AND grirdate > '01-apr-2013')
AND grirno IS NOT NULL
AND chkuser IS NOT NULL
AND grirdate > '01-apr-2013'
ORDER BY TO_NUMBER (SUBSTR (GRIRNO,INSTR (GRIRNO,'/',1,1)+ 1,( INSTR (GRIRNO,'/',1,2)- INSTR (GRIRNO,'/',1,1)- 1))) DESC
您的子查询实际上似乎与外部查询完全非相关。因此,Oracle 很可能会执行一次并缓存结果以备后用。我可以建议以下索引:
CREATE INDEX idx ON grirmain (gridate, girano, chksuer);
这个索引至少应该让Oracle能够快速处理WHERE
子句,而且它覆盖了SELECT
子句中的两列。如前所述,不相关的子查询应该执行一次然后缓存。
至于 ORDER BY
子句,索引可能无济于事,Oracle 将不得不手动排序。
我建议使用 NOT EXISTS
:
SELECT m.grirno, m.grirdate
FROM grirmain m
WHERE NOT EXISTS (SELECT 1
FROM grir_pass p
WHERE g.grirno = p.grirno AND
p.ins_check IS NOT NULL AND
p.grirdate > DATE '2018-04-01'
) AND
m.grirno IS NOT NULL AND
m.chkuser IS NOT NULL AND
m.grirdate > DATE '2018-04-01'
ORDER BY TO_NUMBER(SUBSTR (GRIRNO,INSTR (GRIRNO,'/',1,1)+ 1,( INSTR (GRIRNO,'/',1,2)- INSTR (GRIRNO,'/',1,1)- 1))) DESC;
然后,您需要 grir_pass(grirno, grirdate, ins_check)
和 grirmain(grirno, grirdate, chkuser)
上的索引。