PetaPoco 插入 - 最快的方法?

Posted

技术标签:

【中文标题】PetaPoco 插入 - 最快的方法?【英文标题】:PetaPoco Insert - Fastest Method? 【发布时间】:2012-01-31 04:15:16 【问题描述】:

将记录插入数据库的最快选项是什么:使用以下哪个选项:

Database.Insert(poco) Database.Insert(tableName, pkName, poco) Database.Save(poco) Database.Save(tableName, pkName, poco)

出于性能原因,我应该使用哪一个?一个对我来说并不比另一个更方便......

谢谢。

【问题讨论】:

【参考方案1】:

出于性能原因,我应该使用哪一个?

Database.Save 方法使用GetValue 检索主键字段的值,然后相应地调用Database.InsertDatabase.Update

因此,只有当您的代码确实需要保存对可能是新的或已存在的对象的更改时,您才应该使用Database.Save。另外请注意,您的表必须有一个自动递增的主键列,Database.Save 才能工作。

即使没有细微的性能差异,我更喜欢正确的语义 - 使用插入或更新而不是保存。

一个对我来说并不比另一个更方便......

这不是真的。

Database.Insert(poco) 将在 poco 类定义的自定义属性中查找 tableNamepkName 的值。如果您使用 T4 模板,这些值将自动与您的数据库保持同步,并且它们只会在一个位置指定。另一方面,如果您在每个方法调用中传递它们,它们将在您的代码库中重复无数次。干燥。如果您以后需要更改其中一个值怎么办?

现在,Database.Insert(poco) 的性能将因该查找而略低。但是,PetaPoco 将该查找的结果缓存在静态字典中,因此第一次查找后对性能的影响将非常小:

RWLock.EnterReadLock();
PocoData pd;
try

    if (m_PocoDatas.TryGetValue(t, out pd))
        return pd;

finally

    RWLock.ExitReadLock();

【讨论】:

是的,通过这句话“一个对我来说并不比另一个更方便......”,我所做的补救措施是:blogs.msmvps.com/bmains/2011/12/31/… Violation of DRY,是的,但它更好根据此进行性能:toptensoftware.com/Articles/94/PetaPoco-More-Speed。我也可能会尝试将自定义更进一步... @BrianMains:你真的需要挤出一点额外的速度吗?我使用定制的 SubSonic 模板有一段时间了(我们仍然在我们维护的应用程序中使用它们),这是一个拖累。无论如何,我认为我已经在我的回答中清楚地列出了权衡。您当然可以选择更快的路线而不是更容易维护的路线,但很少有人真正需要它。最大的收益将来自批处理操作、准备好的语句、适当的索引等。 但是您说的是 9 毫秒左右超过 500 次迭代,因此性能损失可以忽略不计。数据库将成为映射代码之前的瓶颈。 @BrianMains:我在阅读您的博客文章时注意到的另一件事是,通过您使用的修改,您放弃了对 poco 进行多态操作的能力。例如,我在一个使用 PetaPoco 的项目中实现了 UnitOfWork 类,该类依赖于多态跟踪所有更改的对象 - 如object's,并一次提交所有更改。显然,您可能不需要这种能力 - 但例如,必须知道 poco 类才能使用 Users.GetTableName(),这是一种权衡。 @qes 感谢您从各个角度看待它。说真的,我很感激。是的,工作单元在许多流行的框架中实现,例如实体框架 L2SQL、NHibernate,并且是一个不错的功能。它可能会导致大型对象图的一些性能问题并跟踪大量更改的对象(使用 EF 体验过)。在我的场景中,它是一个简单的应用程序,而这一切都是多余的。但是,对于这篇文章的未来读者来说,有些事情需要考虑。【参考方案2】:

在您列出的所有 4 个方法中,对于插入,看起来 PetaPoco 总是调用 Database 类的以下方法:

public object Insert(string tableName, string primaryKeyName, bool autoIncrement, object poco)

Database.Insert(tableName, pkName, poco) 的工作量最少(它基本上只是一种传递方法),所以我认为它是性能最好的方法。

这是Insert(string, string, object)的代码:

public object Insert(string tableName, string primaryKeyName, object poco)

    return Insert(tableName, primaryKeyName, true, poco);

直接调用Insert(string, string, bool, object) 重载可能会稍微快一些(并且不明显)。

【讨论】:

以上是关于PetaPoco 插入 - 最快的方法?的主要内容,如果未能解决你的问题,请参考以下文章

PetaPoco微型ORM的使用错误记录

PetaPoco 批量插入数据

PetaPoco 在带触发器的表上插入失败

添加/插入 petapoco vs dapper 的风格

PetaPoco - 如何关闭自动增量?

使用 PetaPoco 插入时如何处理数据库中的 DEFAULT 值?