C# 如何优化RavenDB查询以检索所有文档?

C# 如何优化RavenDB查询以检索所有文档?,c#,ravendb,document-database,C#,Ravendb,Document Database,我正在尝试学习如何使用RavenDB,为此我创建了一个基本示例。 似乎初始化存储和查询需要花费大量的时间 static void Main(字符串[]args) { const bool createNewEntities=true; var sw=新秒表(); 使用(var store=new embeddedabledocumentstore{DataDirectory=“~\\Data”}) { sw.Start(); store.Initialize(); sw.Stop(); Writ

我正在尝试学习如何使用RavenDB,为此我创建了一个基本示例。 似乎初始化存储和查询需要花费大量的时间

static void Main(字符串[]args)
{
const bool createNewEntities=true;
var sw=新秒表();
使用(var store=new embeddedabledocumentstore{DataDirectory=“~\\Data”})
{
sw.Start();
store.Initialize();
sw.Stop();
WriteLine(“在{0}毫秒内初始化”,sw.elapsedmillishes);
如果(createNewEntities)
{
sw.Reset();
sw.Start();
使用(var session=store.OpenSession())
{
sw.Stop();
Console.WriteLine();
WriteLine(“在{0}毫秒内打开的会话”,sw.elapsedmillishes);
对于(变量i=0;i<10;i++)
{
var entity=newentitya(“entity A”+DateTime.Now.ToLongTimeString());
sw.Reset();
sw.Start();
会话存储(实体);
sw.Stop();
如果(i<3)
WriteLine(“存储在{1}ms.”中的“{0}”,entity.Name,sw.elapsedmillesons);
}
sw.Reset();
sw.Start();
session.SaveChanges();
sw.Stop();
WriteLine(“以{0}毫秒为单位保存的更改”,sw.elapsedmillesons);
}
}
sw.Reset();
sw.Start();
使用(var session=store.OpenSession())
{
sw.Stop();
Console.WriteLine();
WriteLine(“在{0}毫秒内打开的实体会话”,sw.elapsedmillesons);
sw.Reset();
sw.Start();
var entities=session.Query().ToArray();
sw.Stop();
WriteLine(“在{1}毫秒内查询所有{0}EntityA”,entities.Length,sw.ElapsedMilliseconds);
}
sw.Reset();
sw.Start();
使用(var session=store.OpenSession())
{
sw.Stop();
Console.WriteLine();
WriteLine(“在{0}毫秒内(再次)打开了一个会话的实体”,sw.elapsedmillesons);
sw.Reset();
sw.Start();
var entities2=session.Query().ToArray();
sw.Stop();
WriteLine(“在{1}毫秒内(再次)查询所有{0}实体”,实体2.Length,sw.elapsedmillisons);
}
}
Console.WriteLine();
Console.WriteLine();
Console.WriteLine(“按ENTER键退出…”);
Console.ReadLine();
}
这将产生以下输出:

Initialized in 6132 ms. Opened session in 3 ms. Stored 'Entity A 08:50:14' in 129 ms. Stored 'Entity A 08:50:15' in 0 ms. Stored 'Entity A 08:50:15' in 0 ms. Saved changes in 29 ms. Opened EntityA session in 0 ms. Queried for all 10 EntityA in 463 ms. Opened EntityA session (again) in 0 ms. Queried (again) for all 10 EntityA in 1 ms. 初始化时间为6132毫秒。 在3毫秒内打开会话。 在129毫秒内存储“实体A 08:50:14”。 在0毫秒内存储“实体A 08:50:15”。 在0毫秒内存储“实体A 08:50:15”。 在29毫秒内保存更改。 已在0毫秒内打开EntityA会话。 在463毫秒内查询所有10个实体。 在0毫秒内(再次)打开EntityA会话。 在1毫秒内(再次)查询所有10个实体。 从这个粗略的例子中,我可以看出:

  • 初始化商店需要花费大量时间
  • 存储第一个实体(共十个)需要相当长的时间
  • 第一次查询所有实体要花很多时间,但第二次根本不需要时间
如何正确查询数据库中特定类型(EntityA)的所有文档? 当然,RavenDB不可能要求每个查询都有索引吗?特别是对于没有任何条件的查询


(注意:我打算使用嵌入在桌面应用程序中的DB,其中列出所有文档用于显示DB的内容。)

以下是三个延迟的原因:

初始化延迟
初始化文档存储确实是最昂贵的操作之一。由于您运行的是RavenDB的嵌入式模式,因此它不仅需要建立到数据库的连接,实际上还需要启动数据库运行。在我的机器(2.3Ghz i5笔记本电脑)上,初始化需要2516毫秒

如果您运行的是一个完整的RavenDB服务器(不是嵌入式的),那么大部分延迟将发生在启动服务器本身时。初始化客户机将大大加快速度

考虑到
IDocumentStore
(无论是嵌入式的还是普通的)是作为一个单例保存的,这是合理的行为。在您的应用程序中应该只有一个这样的实例,它应该在启动时创建,在关闭时处理

首次存储延迟
因为您没有提供自己的
Id
,Raven会使用自己的。这涉及到从数据库分配一个可分配ID块,这只需要很少的时间。后续调用将更快,因为在块用完之前,它们不必访问数据库

如果您提供自己的
Id
属性,并使用有效标识符(如
entities/1
entities/2
)等)填充该属性,则会更快,因为您将跳过密钥生成

查询延迟
当您没有指定静态索引时,第一次调用
.Query()
将尝试创建与查询表达式匹配的动态索引。即使在获取“所有”实体时也是如此,因为它仍然必须使用
Raven entity Name
元数据按实体类型进行过滤。在RavenDB中,是一个虚拟的东西,由元数据决定。文档实际上是共同存在的——因此,除了通过元数据进行查询和过滤之外,没有其他方法可以获取“集合”中的所有项

您看到的部分延迟是正在构造的动态索引。然后,要编制索引的项目会有一个延迟。请注意,如果您添加了更多的项目(比如几百个),您仍然可以使用ge
session.Advanced.LoadStartingWith<EntityA>("EntityAs/");