I've just started doing some real-world performance testing on my Fluent NHibernate / SQLite project, and am experiencing some serious delays when when I Commit to the database. By serious, I mean taking 20 - 30 seconds to Commit 30 K of data!
This delay seems to get worse as the database grows. When the SQLite DB file is empty, commits happen almost instantly, but when it grows to 10 Meg, I see these huge delays.
The database has 16 tables, averaging 10 columns each.
One possible problem is that I'm storing a dozen or so IList<float>
members, but they are typically only 200 elements long. But this is a recent addition to Fluent NHibernate automapping, which stores each float in a single table row, so maybe that's a potential problem.
Any suggestions on how to track this down? I suspect SQLite is the culprit, but maybe it's NHibernate?
I don't have any experience with profilers, but am thinking of getting one. I'm aware of NHibernate Profiler - any recommendations for profilers that work well with SQLite?
Edit
Some more testing indicates that it's not the size of the database that causes the slowdown - it's dependent on how many Saves I've done since I started my program. Commit time for the first Save is about 300 ms, and goes to over 1000 ms by the 50th Save.
I'm keeping a single Session open all the time - maybe I need some explicit Flush logic?
Also, I downloaded the NHibernate Profiler. It gave me an alert about "Large number of individual writes" for my IList members. The alert description suggested turning on batching, but SQLite does not support that, as far as I can tell.
Also mentioned Multiquery support, so I'm going to read up on that.
/Edit
Here's the method that saves the data - it's just a SaveOrUpdate call and a Commit, if you ignore all the error handling and debug logging.
public static void SaveMeasurement(object measurement)
{
Debug.WriteLine("\r\n---SaveMeasurement---");
// Get the application's database session
var session = GetSession();
using (var transaction = session.BeginTransaction())
{
try
{
session.Save(measurement);
}
catch (Exception e)
{
throw new ApplicationException(
"\r\n SaveMeasurement->SaveOrUpdate failed\r\n\r\n", e);
}
try
{
Debug.WriteLine("\r\n---Commit---");
transaction.Commit();
Debug.WriteLine("\r\n---Commit Complete---");
}
catch (Exception e)
{
throw new ApplicationException(
"\r\n SaveMeasurement->Commit failed\r\n\r\n", e);
}
}
}