NHibernate로 대량 삽입 작업 속도 향상
벌크 속도를 높이고 싶습니다.insert
Oracle 11g에서 NHibernate 3.2를 사용한 운영.이를 위해 노력했습니다.
Session.Save(entity);
Session.Flush();
Session.Clear();
내 안에서foreach
루프이지만 세션에서 누락된 개체로 인해 예외가 발생했습니다.
역할 컬렉션인 MyClass를 게으르게 초기화하지 못했습니다.속성 X, 세션 또는 세션이 닫히지 않았습니다.
또 다른 시도는 배치 크기를 설정하는 것이었습니다.
<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)
내 코드에서 다음과 같은 예외가 발생했습니다.
세션 팩토리에 대해 정의된 배치 크기가 없습니다. 배치를 사용할 수 없습니다.donet.batch_size = 1을 설정하여 배치를 사용하도록 설정합니다.
이 예외가 발생하는 유일한 위치는 NonBatchingBatcher입니다. 그래서 제 세션에 잘못된 배처가 있는 것 같습니다.
여기서 뭐가 문제야?정적 세션을 사용하지 않고 NHibernate로 배치 삽입 속도를 높이려면 어떻게 해야 합니까?
다음이 효과가 있을 것입니다.
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
위의 모든 팁은 매우 유효하고 매우 유용합니다.컬렉션에 하나를 추가하려고 했습니다. 로깅을 사용하지 않도록 설정하십시오.콘솔에 SQL이 표시되면 NHProf를 사용한 프로파일링, 자동 주석 처리 및 NLog 또는 log4net을 통해 기록된 SQL의 예쁜 포맷과 마찬가지로 속도가 현저하게 느려집니다.이 경우 설정:
cfg.AutoCommentSql = false;
cfg.LogFormattedSql = false;
대량 삽입 시간을 ~6초에서 1초 이상으로 단축했습니다.따라서 벌목은 잠재적으로 더 심각한 문제를 해결하는 데 도움이 될 수 있지만, 그 자체로 성능이 크게 향상됩니다!
- http://davybrion.com/blog/2008/10/bulk-data-operations-with-nhibernates-stateless-sessions
- http://martin.podval.eu/2010/12/nhibernate-performance-isssues-insert.html
읽을 가치가 있는 두 번째 URL입니다.
세션을 삭제하는 이유는 무엇입니까?
루프에서 세션을 삭제하면 안 된다고 생각합니다.변경사항이 데이터베이스에 기록되도록 하려면 트랜잭션을 사용하는 것이 좋습니다.
의사 코드:
foreach (var i in allElements)
{
using (var tx = session.BeginTransaction())
{
... do what you have to do with the object
tx.Commit();
}
}
속도를 높이기 위해서는 루프에서 실제로 무엇을 하고 싶은지 정의해야 합니다.
Oracle에 대한 질문이었지만 SQL Server의 경우 클래스 매핑을 가져오고 SQLBulkInsert에서 사용할 DataTable을 생성하는 루틴을 작성하려고 했지만 이미 누군가가 이 작업을 수행했다는 것을 알게 되었습니다.
https://kaylaniam.wordpress.com/2015/03/13/nhibernate-and-sqlbulkcopy/
SQL Server에서 대량 삽입을 수행하는 가장 빠른 방법입니다.
아래 코드는 여러 개의 복합 엔티티를 삽입하는 데 사용됩니다.
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 개체를 채우는 메서드를 만들어야 합니다.
언급URL : https://stackoverflow.com/questions/9943967/speed-up-bulk-insert-operations-with-nhibernate
'source' 카테고리의 다른 글
mariadb 10.3.3을 10.5.5로 업그레이드합니다. 단계를 안내해 주시겠습니까? (0) | 2023.08.15 |
---|---|
content-Type: application/js를 node.js와 함께 게시합니다. (0) | 2023.08.15 |
Android에서 임시 파일 만들기 (0) | 2023.08.10 |
Android 수행 표시줄 제목 및 아이콘을 변경하는 방법 (0) | 2023.08.10 |
인쇄 문으로 저장 프로시저를 디버깅하는 방법은 무엇입니까? (0) | 2023.08.10 |