我在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
);
答案 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_EMPLOYEE
和BI_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
还有其他选择:
答案 5 :(得分:0)
我只是添加除了为查询创建索引之外的其他内容,您需要在表格变大时查看锁定问题,尝试以独占模式锁定表格(如果可能),因为这样做只从数据库中获取一个锁,如果不可能尝试在每个2500条记录上提交删除,那么如果您遇到行锁定,则不会最终使锁定数据库挨饿。