2

我们在多租户环境中使用 RavenDB,用户可以创建自己的租户并在那里创建自己的应用程序。

然而问题是他们的数据库不时空闲(当然在接受,但它也发生在生产中),并且由于某种原因重新加载它需要超过 40 秒。但是我们只有约 1000 个文档和约 300 个索引(这是应用程序的蓝图,一旦投入生产,它应该包含更多文档),并且所有索引都有一个单独的子句Map和一个 -TransformResults子句。

版本:2.0.2230 和 2.0.2261(截至撰写时的最新稳定版本)

一般统计

 ...
TransactionalStorageSize:26222592,
TransactionalStorageSizeHumaneSize:"25.01 MBytes",
IndexStorageSize:376263,
IndexStorageHumaneSize:"367.44 KBytes",
TotalDatabaseSize:26598855,
TotalDatabaseHumaneSize:"25.37 MBytes",
CountOfDocuments:975,
...

数据库统计

CountOfIndexes:305,
InMemoryIndexingQueueSize:0,
ApproximateTaskCount:0,
CountOfDocuments:975,
StaleIndexes:[],
CurrentNumberOfItemsToIndexInSingleBatch:256,
CurrentNumberOfItemsToReduceInSingleBatch:128,
DatabaseTransactionVersionSizeInMB:0.02,
....
Errors:[],
....

编辑

我们正在谈论的应用程序有两个组件,一个设计器和一个运行时。在 ravendb 中,我们存储设计和在运行时创建/使用的数据。每个租户都是一个应用程序。

我们有这么多索引,因为对于您在设计模式中创建的每个查询,我们都会在 ravendb 中创建一个索引。

索引具有以下形式: Map from ... [from...|let...] [where ... ] select ...with LoadDocument 调用以加载给定 lucene 查询所需的关联文档,以及类似的 TransfromResults 以将文档塑造成所需形式。

我将研究我们是否可以放松查询和索引之间的一对一耦合。

问:最好有几个巨大的索引,假设我们查询的每个实体都有一个,还是找到一些中间地带?

问:目前我们不允许在我们的实体设计中包含“复杂”实体,即除了价值属性或对其他文档的引用之外什么都没有,如果我们有更少和更大的文档,这会产生影响吗?因此必须减少调用LoadDocument(...)

这需要这么长时间(40 秒)有什么原因吗?任何减轻这种情况的可能方法将不胜感激。

4

2 回答 2

3

回答这个问题的 1 个子问题:

问:最好有几个巨大的索引,假设我们查询的每个实体都有一个,还是找到一些中间地带?

在正常情况下,每个实体类型永远不需要超过 1 个索引。

如果你有几十个实体类型,你很可能掉进了将 RDBMS 模型设计应用于非关系设计的坑。客观地说,我们有一个功能丰富的系统,它建立在总共 8 个聚合根之上。有 2-3 个支持基础设施实体。

我们共有 17 个索引。8 个 Map、5 个 Multi-map 和 5 个 map-reduce。如您所见,我们有 1:1 的 Map:Aggregate Root 索引。具有用于支持聚合搜索和自定义结果的映射/减少的附加索引。

于 2013-03-08T18:32:56.073 回答
2

有一件事我觉得有点奇怪 - 您的索引与文档的比率似乎有点高。为什么需要这么多索引?你能合并它们吗?

例如,如果您在同一实体上有一些仅映射索引,例如:

// index 1
Map = customers => from customer in customers
                   select new
                   {
                       customer.FirstName
                   }

// index 2
Map = customers => from customer in customers
                   select new
                   {
                       customer.LastName
                   }

显然,这些可以在一个索引中:

Map = customers => from customer in customers
                   select new
                   {
                       customer.FirstName,
                       customer.LastName
                   }

如果您可以降低索引计数,它将显着降低服务器的压力。

请记住,所有索引都针对所有文档运行。在他们翻译的地图中,您会看到docs.customer- 这是Raven-Entity-Type元数据过滤的简写。

因此,如果您有 1000 个文档针对 300 个索引,则需要对地图进行 300,000 次评估。如果您要将索引减少到更常见的值 - 比如 20 左右,那会表现得更好。

于 2013-03-08T13:37:29.703 回答