【问题标题】:Speed up bulk insert operations with NHibernate使用 NHibernate 加速批量插入操作
【发布时间】:2012-04-14 04:44:00
【问题描述】:

我想在 Oracle 11g 上使用 NHibernate 3.2 加快批量 insert 操作。为此,我尝试了

Session.Save(entity);
Session.Flush();
Session.Clear();

...在我的foreach 循环中,但由于会话中缺少对象而导致异常:

未能延迟初始化角色集合:MyClass.PropertyX,没有会话或会话已关闭

另一种尝试是设置批量大小:

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory>
    <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
    <property name="connection.driver_class">NHibernate.Driver.OracleClientDriver</property>
    <property name="connection.connection_string">xxx</property>
    <property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>
    <property name="adonet.batch_size">50</property>
    <property name="query.substitutions">true=1, false=0</property>
    <property name="proxyfactory.factory_class">NHibernate.Bytecode.DefaultProxyFactoryFactory, NHibernate</property>
  </session-factory>
</hibernate-configuration>

另外我在我的代码中设置了Session.SetBatchSize(50) 得到了以下异常:

没有为会话工厂定义批处理大小,批处理是 禁用。设置 adonet.batch_size = 1 以启用批处理。

引发此异常的唯一位置是NonBatchingBatcher,因此看来我的会话使用了错误的批处理器。

这里有什么问题?如何使用 NHibernate 加快批量插入(不使用无状态会话)?

【问题讨论】:

  • 您的第一个例外究竟是什么?此外,如果您在 循环内 执行 Flush,您将不会批处理任何内容。
  • @Diego Mijelshon 添加了异常消息
  • @deamon 这是多线程的吗?

标签: .net performance oracle nhibernate orm


【解决方案1】:

以下应该可以工作,

var testObjects = CreateTestObjects(500000);

var stopwatch = new Stopwatch();
stopwatch.Start();
using (IStatelessSession session = sessionFactory.OpenStatelessSession())
using (ITransaction transaction = session.BeginTransaction())
{
    foreach (var testObject in testObjects)
        session.Insert(testObject);
    transaction.Commit();
}

stopwatch.Stop();
var time = stopwatch.Elapsed;

参考:http://nhibernate.info/blog/2008/10/30/bulk-data-operations-with-nhibernate-s-stateless-sessions.html

【讨论】:

  • 我应该在使用无状态会话后清除缓存吗?还是有状态会话会接收无状态会话所做的更改?
【解决方案2】:

以上所有提示都非常有效且非常有用。想要向集合中添加一个:禁用日志记录。在控制台中显示 SQL 会明显减慢您的速度,使用 NHProf 进行分析、自动注释和漂亮格式化通过 NLog 或 log4net 记录的 SQL 也是如此。在我们的案例设置中:

cfg.AutoCommentSql = false;
cfg.LogFormattedSql = false;

将我们的批量插入时间从大约 6 秒减少到 1 秒多一点。因此,虽然日志记录可能会帮助您解决更严重的问题,但它本身会带来性能损失!

【讨论】:

    【解决方案3】:
    【解决方案4】:

    你为什么要清除会话?

    我认为您不应该清除循环中的会话。为了确保将更改写入数据库,我宁愿使用事务。

    伪代码:

    foreach (var i in allElements)
    {
        using (var tx = session.BeginTransaction())
        {
            ... do what you have to do with the object
            tx.Commit();
        }
    }
    

    为了加快速度,还有其他可能会有所帮助的事情 - 您必须在循环中定义您真正想要做的事情。

    【讨论】:

      【解决方案5】:

      我知道这个问题是关于 Oracle 的,但是对于 SQL 服务器,我打算编写一个例程来获取类映射并生成一个 DataTable 供 SqlBulkInsert 使用,但我发现有人已经这样做了。

      https://kaylaniam.wordpress.com/2015/03/13/nhibernate-and-sqlbulkcopy/

      这可能是在 SQL Server 上进行批量插入的最快方法。

      【讨论】:

        【解决方案6】:

        下面的代码适用于我插入多个复合实体

         public static void SqlBulkInsert(this ISession session, DataTable dataTable, string tableName)
            {
                var conn = (SqlConnection)session.Connection;
                using (var cmd = new SqlCommand())
                {
                    session.Transaction.Enlist(cmd);
                    using (var copy = new SqlBulkCopy(conn, SqlBulkCopyOptions.FireTriggers, cmd.Transaction))
                    {
                        copy.BulkCopyTimeout = 10000;
                        copy.DestinationTableName = tableName;
                        foreach (DataColumn column in dataTable.Columns)
                        {
                            copy.ColumnMappings.Add(column.ColumnName, column.ColumnName);
                        }
        
                        copy.WriteToServer(dataTable);
                        copy.Close();
                    }
                }
            }
        

        你必须创建一个方法来从你想要持久化的复合实体对象中填充一个 DataTable 对象。

        【讨论】:

          猜你喜欢
          • 2018-03-14
          • 2011-06-11
          • 2011-05-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-01-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多