通过实体框架选择优化方式删除oracle中的行
Posted
技术标签:
【中文标题】通过实体框架选择优化方式删除oracle中的行【英文标题】:Selecting optimize way to delete rows in oracle though entity framework 【发布时间】:2016-06-15 09:34:22 【问题描述】:我有一个场景,我必须定期删除数十万行(基于服务器决策或某个固定时间间隔)。我正在使用 entityframework 6.0,问题是正常的 Remove() 方法对于批量操作来说很慢。我正在考虑一些可能的情况:
案例1:通过实体框架,使用RemoveRange。
var db = new MyDbContext();
var itemsToDelete = db.TableFoo.Where(x=>!x.new);
db.MyTable.RemoveRange(itemsToDelete);
db.SaveChanges();
我检查了这个,这比在 foreach 中单独使用 Remove 更快。但它仍然发送oracle atomic sql而不是batch。
案例 2: 通过实体框架调用某个过程或包,这些过程或包反过来会对表执行删除操作。虽然在我看来它是最快的选择,但我仍然必须在这里弄清楚什么是最好的 sql 删除方式,我知道截断,但它在这里不起作用。我知道的是:
CREATE OR REPLACE PROCEDURE deleteDBFoo(p_toc IN DBFOO.TOC%TYPE)
IS
BEGIN
DELETE DBFOO where TOC < "SOME DATE";
COMMIT;
END;
案例 3: 要在 oracle 中自动执行此任务(不知道这是否可行或好主意),以防万一标准是从某个固定日期时间间隔中删除所有旧行。
处理这种情况的优化方法是什么?如果除了这些情况之外还有其他更好的方法,请说明这一点。
UPDATE1:在进行了一些分析后,我发现了以下结果:
用于删除数据库中的 100 万行
Trunc Table 耗时 3.46 秒。 案例 2:耗时 37.398 秒 案例1:花了几分钟。 对于我的解决方案,我将使用案例 2,但我仍然等待比案例 2 更好的解决方案或以某种方式改进它。
【问题讨论】:
【参考方案1】:删除批量数据最快的方法是在服务器端进行。
在你的情况下,因为你想使用实体框架,你应该创建一个带有参数的存储过程,并从代码中 execute 这个存储过程。
如果要使用案例1,实体框架会很慢;因为每次删除它都会创建一个查询并执行它。
试试这样的:
CREATE OR REPLACE PROCEDURE DeleteUnnecessaryData
(endDate IN DATE)
IS
BEGIN
DELETE DBFOO where TOC < endDate;
COMMIT;
END;
【讨论】:
“在服务器端做”如何?你的意思是使用一些触发器?第二点您的解决方案看起来像案例 2,您对我编写的存储过程感到满意还是有更好的方法来做到这一点。第三点是的,我同意你关于案例 1 :) 当您创建存储过程时,您只向服务器发送执行查询的命令;从存储过程中删除是在服务器上执行的。 你写了类似 db.Database.SqlQuery("exec DeleteUnnecessaryInfo @startdate ", startdateParam) 啊.. 我想你应该通过一些逻辑触发器或通过实体框架应用程序直接在 oracle 上调用它。 我将测试这个案例 2,并在每种情况下用适当的时间更新我的问题。那么我认为它会更有意义。以上是关于通过实体框架选择优化方式删除oracle中的行的主要内容,如果未能解决你的问题,请参考以下文章