我们在多租户环境中使用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中创建一个索引。
索引具有以下形式:使用LoadDocument调用映射from ... [from...|let...] [where ... ] select ...
以为给定的lucene查询加载所需的关联文档,并使用类似的TransfromResults来形成所需形式的文档。
我将研究是否可以放松查询和索引之间的一对一耦合。
问:拥有一些巨大的索引是否更好,让我们为每个查询的实体说一个,或者找一些中间地点?
问:目前我们不允许我们设计的实体拥有“复杂”实体,即只有价值属性或对其他文件的引用,如果我们的数量更少,更大,这会产生影响文件,因此必须少打电话LoadDocument(...)
?
这是否需要这么长时间(40s)? 任何可能的缓解方法都将受到赞赏。
答案 0 :(得分:3)
回答1:
的问题问:拥有一些巨大的索引是否更好,让我们分别说一个 我们查询的实体,或找到一些中间地点?
在正常情况下,每个实体类型永远不会需要超过1个索引。
如果你有几十种实体类型,你可能已经陷入了将RDBMS模型设计应用于非关系设计的陷阱。从透视角度来看,我们有一个功能丰富的系统,它建立在总共8个聚合根之上。拥有2-3个支持基础设施的实体。
我们共有17个索引。 8个地图,5个多地图和5个地图缩小。如您所见,我们的Map:Aggregate Root索引的比率为1:1。使用其他索引支持聚合搜索和map / reduce自定义结果。
答案 1 :(得分: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
元数据的简写。
因此,如果您对300个索引有1000个文档,那么地图必须评估300,000次。如果你要将索引减少到更常见的东西 - 比如20左右,那就会表现得更好。