我在Oracle 10g中有这个查询:
DELETE FROM "BMAN_TP1"."CELLS_ITEM" TABLE1
WHERE EXISTS (
SELECT "CELLS_ITEM".*
FROM "BMAN_TP1"."CELLS_ITEM"
INNER JOIN "BMAN_TP1"."CELLS" ON ("CELLS_ITEM"."SET_ID"="CELLS"."SET_ID") AND ("CELLS_ITEM"."META_CELL_ID"="CELLS"."META_CELL_ID")
INNER JOIN "BMAN_TP1"."META_CELLS" ON ("CELLS"."META_CELL_ID"="META_CELLS"."META_CELL_ID")
WHERE ("META_CELLS"."UDA_ID" = variable)
AND (TABLE1."SET_ID" = "CELLS_ITEM"."SET_ID")
AND (TABLE1."META_CELL_ID" = "CELLS_ITEM"."META_CELL_ID")
)
目前需要大约10秒才能删除50K记录(表中约有100K记录)
我知道它会重复选择查询的100倍,这会大大减慢它的速度 TABLE1还有一个双字段PK,这使事情变得更加复杂。
任何让它更快的想法?
编辑:
试过这个,但它几乎一样:
DELETE FROM "BMAN_TP1"."CELLS_ITEM" TABLE1
WHERE EXISTS (
SELECT "META_CELL_ID"
FROM "BMAN_TP1"."META_CELLS"
WHERE ("META_CELLS"."UDA_ID"=55823)
AND (TABLE1."META_CELL_ID" = "META_CELLS"."META_CELL_ID")
)
答案 0 :(得分:4)
在不知道您的架构的情况下,很难说,但是在子查询中使用要删除的表似乎毫无用处。我会改为写:
DELETE FROM BMAN_TP1.CELLS_ITEM TABLE1
WHERE EXISTS (
SELECT CELLS.META_CELL_ID
FROM BMAN_TP1.CELLS
INNER JOIN BMAN_TP1.META_CELLS ON (CELLS.META_CELL_ID=META_CELLS.META_CELL_ID)
WHERE (META_CELLS.UDA_ID = variable)
AND (TABLE1.SET_ID = CELLS_ITEM.SET_ID)
AND (TABLE1.META_CELL_ID = CELLS_ITEM.META_CELL_ID)
)
编辑:由于您修改了DELETE
声明,因此上述日期已过时。请忽略它。
但另一个想法是:如果在CELLS_ITEM上定义了触发器,您可以尝试禁用它们。他们可以长时间咀嚼更大的删除,我直接了解它。
答案 1 :(得分:2)
第一个可能的答案:只需在SET_ID,META_CELL_ID上的CELLS_ITEM表中添加一个索引
第二个可能的答案:尝试标准的SQL语法:
DELETE "BMAN_TP1"."CELLS_ITEM"
FROM BMAN_TP1"."CELLS_ITEM"
INNER JOIN "BMAN_TP1"."CELLS" ON ("CELLS_ITEM"."SET_ID"="CELLS"."SET_ID") AND ("CELLS_ITEM"."META_CELL_ID"="CELLS"."META_CELL_ID")
INNER JOIN "BMAN_TP1"."META_CELLS" ON ("CELLS"."META_CELL_ID"="META_CELLS"."META_CELL_ID")
WHERE ("META_CELLS"."UDA_ID" = variable)
- 的修改
好的,如果Oracle不接受标准的SQL方式(听起来很奇怪)那么你可以尝试使用IN:
DELETE "BMAN_TP1"."CELLS_ITEM"
WHERE (SET_ID, META_CELL_ID) IN (SELECT SET_ID, META_CELL_ID
FROM BMAN_TP1"."CELLS_ITEM"
INNER JOIN "BMAN_TP1"."CELLS" ON ("CELLS_ITEM"."SET_ID"="CELLS"."SET_ID") AND ("CELLS_ITEM"."META_CELL_ID"="CELLS"."META_CELL_ID")
INNER JOIN "BMAN_TP1"."META_CELLS" ON ("CELLS"."META_CELL_ID"="META_CELLS"."META_CELL_ID")
WHERE ("META_CELLS"."UDA_ID" = variable) )
但我认为EXISTS查询应该比这个更快......这会使添加索引答案成为您的最佳选择。但是,可以肯定的是,首先尝试这种新方法。
答案 2 :(得分:1)
试试这个:
DELETE FROM (SELECT TABLE1.* FROM "BMAN_TP1"."CELLS_ITEM" TABLE1
INNER JOIN (
SELECT "META_SET_ID", "META_CELL_ID"
FROM "BMAN_TP1"."META_CELLS"
WHERE "UDA_ID"=55823
) j ON TABLE1."SET_ID" = j."META_SET_ID" AND TABLE1."META_CELL_ID" = j."META_CELL_ID"
)
答案 3 :(得分:1)
我现在无法测试所以不确定,因为我现在无权访问Oracle DB,而是rowid 在某些情况下可能更快:
DELETE "BMAN_TP1"."CELLS_ITEM"
WHERE rowid IN (SELECT rowid
FROM BMAN_TP1"."CELLS_ITEM"
INNER JOIN "BMAN_TP1"."CELLS" ON ("CELLS_ITEM"."SET_ID"="CELLS"."SET_ID") AND ("CELLS_ITEM"."META_CELL_ID"="CELLS"."META_CELL_ID")
INNER JOIN "BMAN_TP1"."META_CELLS" ON ("CELLS"."META_CELL_ID"="META_CELLS"."META_CELL_ID")
WHERE ("META_CELLS"."UDA_ID" = variable) )