如何优化以下删除SQL查询?

时间:2012-09-05 05:25:31

标签: sql oracle optimization

我在oracle中有以下delete查询。一次将从数据库中删除大约1000条记录。

我在查询中使用了“in”。有没有更好的方法来编写这个查询?

DELETE FROM BI_EMPLOYEE_ACTIVITY      
WHERE EMPLOYEE_ID in (    
    SELECT    
      EMP_ID   
    FROM   
      BI_EMPLOYEE   
    WHERE   
      PRODUCT_ID = IN_PRODUCT_ID  
  );

6 个答案:

答案 0 :(得分:0)

将索引放在EMP_ID上可能会有所帮助,我不相信如果可以进行任何其他优化,查询非常简单直接

答案 1 :(得分:0)

在PRODUCT_ID列上创建索引。这会加快搜索速度。如果列是varchar类型,如果要将值转换为大写或小写

,请使用函数索引

答案 2 :(得分:0)

也许你可以试试EXIST而不是IN:

DELETE FROM BI_EMPLOYEE_ACTIVITY      
WHERE EXISTS (    
    SELECT    
      EMP_ID   
    FROM   
      BI_EMPLOYEE   
    WHERE   
      PRODUCT_ID = IN_PRODUCT_ID 
    AND
      EMP_ID =  EMPLOYEE_ID
  );

答案 3 :(得分:0)

按此顺序在BI_EMPLOYEE列的PRODUCT_ID, EMP_ID表上创建索引(首先是product_id)。

在列BI_EMPLOYEE_ACTIVITY

EMPLOYEE_ID表上创建索引

答案 4 :(得分:0)

由于我们缺少对数据分布的描述,因此无法回答这个问题:每个表中有多少行?桌子之间有什么关系?删除会影响多少行?

我将假设两个表都很大(因为这是一个优化问题)并且BI_EMPLOYEEBI_EMPLOYEE_ACTIVITY具有父子1..N关系。

如果受删除影响的行数很少,则意味着没有多少员工具有相同的PRODUCT_ID,并且每个员工的活动都很少。在这种情况下,对BI_EMPLOYEE (product_id)BI_EMPLOYEE_ACTIVITY (employee_id)进行索引是有意义的。

虽然可能不是这种情况,但删除可能会影响很多行。在这种情况下,索引可能是一个障碍。如果删除影响大量行,则最快的访问路径可能是FULL TABLE SCAN + HASH JOIN

我们需要一些指标:删除多少行?多久时间?这是因为大型DML总是需要时间,尤其是DELETE,因为它们会产生最大量的撤销。

"Deleting many rows from a big table"中所解释的那样,大型DELETE还有其他选择:

  1. 重新创建没有删除行的表
  2. 对数据进行分区,进行并行删除
  3. 对数据进行分区,以便通过删除分区来完成删除

答案 5 :(得分:0)

我只是添加除了为查询创建索引之外的其他内容,您需要在表格变大时查看锁定问题,尝试以独占模式锁定表格(如果可能),因为这样做只从数据库中获取一个锁,如果不可能尝试在每个2500条记录上提交删除,那么如果您遇到行锁定,则不会最终使锁定数据库挨饿。