SQL优化:删除需要很长时间

时间:2010-03-16 15:58:29

标签: sql oracle optimization stored-procedures plsql

我有一个Oracle SQL查询作为存储过程的一部分:

DELETE FROM item i 
 WHERE NOT EXISTS (SELECT 1 FROM item_queue q WHERE q.n=i.n) 
 AND NOT EXISTS (SELECT 1 FROM tool_queue t WHERE t.n=i.n);

关于表格的一点:

  • item包含大约10k行,n列上有索引
  • item_queue包含约1mil的行,也包含n列上的索引
  • tool_queue包含约5mil的索引行

我想知道查询/子查询是否可以某种方式进行优化以使它们运行得更快,我认为删除通常相当快

7 个答案:

答案 0 :(得分:4)

将您的删除变为选择,然后您可以检查并优化查询部分。

否则请注意 - 删除不是最快的事情。删除时会发生很多事情。

OTOH我认真思考....问题是两个子查询。查询计划是什么样的?

答案 1 :(得分:3)

尝试类似:

 DELETE FROM item WHERE n NOT IN 
     (SELECT i.n FROM item i INNER JOIN item_queue q ON i.n = q.n
      UNION SELECT i.n FROM item i INNER JOIN tool_queue t ON i.n = t.n)

您的相关子查询在您的示例中分别运行了10K次。此技术将运行两个INNER JOIN查询以获取要删除的“n”列表。

您可能需要稍微调整一下SQL;我不熟悉Oracle方言。

答案 2 :(得分:1)

请尝试避免在您的Quires中进行Subselect并改为使用INNER JOIN

答案 3 :(得分:1)

确保对引用项表的大型表没有约束。在删除的情况下,这可能是一个真正的减速。

答案 4 :(得分:1)

如果不做额外的工作,你无法真正得到一个好的答案。

在SQL语句iteself之后,最重要的是对象的统计信息(本例中的表和索引)具有代表性。

然后你真的需要查看oracle选择的访问路径 - 许多方法都可以做到这一点。

尝试

EXPLAIN PLAN SET STATEMENT_IS = 'SQL01' FOR
DELETE FROM item i 
 WHERE NOT EXISTS (SELECT 1 FROM item_queue q WHERE q.n=i.n) 
 AND NOT EXISTS (SELECT 1 FROM tool_queue t WHERE t.n=i.n);

然后

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

也许在这里发布结果。

当您尝试不同的事情 - 例如重写查询,修改索引等时,您会注意到访问路径发生了变化。

这是一个相当复杂的领域 - 你需要学习/练习。

由于多种原因,删除速度很慢,但一个重要因素是维护表上的索引。但是,在您的情况下,您说只有10k行非常小。 (顺便说一下,你没有在这里给出时间。目前是花了1,10或100秒?你想要达到什么目标?)所以我会专注于通过更大的桌子的访问路径。

我的第一种方法可能是:

DELETE FROM item i 
 WHERE NOT EXISTS 
(SELECT NULL
 FROM item_queue q,
      tool_queue g
  where q.key = g.key      -- if the tables are related
    AND q.n=i.n) ;

但正如我所说,这里有很多因素。

答案 5 :(得分:0)

尝试使用SELECT而不是delete来查看DELETE操作真正的瓶颈

答案 6 :(得分:0)

虽然它可能不会更快,但如果你这样做会更容易阅读:

DELETE FROM item i 
WHERE n NOT IN (SELECT n FROM item_queue)
AND n NOT IN (SELECT n FROM tool_queue)
相关问题