我们需要每秒存储来自多个设备的 500 个测量值。每个度量都包含一个时间戳、一个数量类型和几个向量值。现在每个测量有 8 个向量值,我们可以认为这个数字是恒定的,以满足我们原型项目的需要。我们正在使用 HNibernate。测试在 SQLite 中完成(磁盘文件 db,而不是在内存中),但生产可能是 MsSQL。
我们的 Measurement 实体类是一个包含单个测量值的实体类,如下所示:
public class Measurement
{
public virtual Guid Id { get; private set; }
public virtual Device Device { get; private set; }
public virtual Timestamp Timestamp { get; private set; }
public virtual IList<VectorValue> Vectors { get; private set; }
}
矢量值存储在一个单独的表中,因此它们中的每一个都通过外键引用其父测量值。
我们做了几件事来确保生成的 SQL(合理)高效:我们使用 Guid.Comb 生成 ID,我们在单个事务中刷新大约 500 个项目,ADO.Net 批量大小设置为 100(我认为 SQLIte 不支持批量更新?但以后可能会有用)。
问题
现在我们可以每秒插入 150-200 个测量值(这还不够快,尽管这是我们正在谈论的 SQLite)。查看生成的 SQL,我们可以看到我们在单个事务中插入(如预期的那样):
- 1 个时间戳
- 1 次测量
- 8 个向量值
这意味着我们实际上做了 10 倍的单表插入:每秒 1500-2000 次。
如果我们将所有内容(所有 8 个向量值和时间戳)放入测量表(添加 9 个专用列),似乎我们可以将插入速度提高 10 倍。
切换到 SQL Server 将提高性能,但我们想知道是否有办法避免与当前数据库组织方式相关的不必要的性能成本。
[编辑]
使用内存中的 SQLite,我可以获得大约 350 个项目/秒(3500 个单表插入),我相信这与 NHibernate 一样好(以这篇文章作为参考:http ://ayende.com/Blog/archive/ 2009/08/22/nhibernate-perf-tricks.aspx)。
但我不妨切换到 SQL Server 并停止假设,对吧?我会在测试后立即更新我的帖子。
[更新]
我已经转移到 SQL Server 并扁平化了我的层次结构,我通过存储 3000 次测量/秒数小时对其进行了测试,它似乎工作正常。