【发布时间】:2018-10-16 19:03:47
【问题描述】:
在 mongodb 中,我有一个特定的集合(发票),在整个应用程序中,我们查询发票并按许多不同的字段进行过滤,如下所示:
public static List<Invoice> FindAll(string userId, Enums.InvoiceType? type = null, string propertyId = null,
string tenantId = null, string landlordId = null, string ownerUserId = null,
bool? isClosed = null, bool? autoGenerated = null, DateTime? startDate = null, DateTime? endDate = null,
int? skip = null, int? take = null) {
var builder = Filter;
var filters = builder.Eq("UserId", userId.ToObjectId());
if (type.HasValue)
filters = filters & builder.Eq("Type", type.Value);
if (!String.IsNullOrEmpty(propertyId))
filters = filters & builder.Eq("PropertyId", propertyId.ToObjectId());
if (!String.IsNullOrEmpty(tenantId))
filters = filters & builder.Eq("TenantId", tenantId.ToObjectId());
if (!String.IsNullOrEmpty(landlordId))
filters = filters & builder.Eq("LandlordId", landlordId.ToObjectId());
if (!String.IsNullOrEmpty(ownerUserId))
filters = filters & builder.Eq("OwnerUserId", ownerUserId.ToObjectId());
if (isClosed.HasValue)
filters = filters & builder.Eq("IsClosed", isClosed.Value);
if (autoGenerated.HasValue)
filters = filters & builder.Eq("AutoGenerated", autoGenerated.Value);
if (startDate.HasValue)
filters = filters & builder.Gte("DueDate", startDate.Value);
if (endDate.HasValue)
filters = filters & builder.Lte("DueDate", endDate.Value);
var result = Collection().Find(filters)
.Sort(Builders<Invoice>.Sort.Descending("DueDate"));
if (skip.HasValue)
result.Skip(skip.Value);
if (take.HasValue)
result.Limit(take.Value);
return result.ToList();
}
因为我们过滤的字段太多,所以我为每个可过滤字段创建了单独的索引:
db.Invoice.ensureIndex( { UserId: 1 } );
db.Invoice.ensureIndex( { Type: 1 } );
db.Invoice.ensureIndex( { PropertyId: 1 } );
db.Invoice.ensureIndex( { TenantId: 1 } );
db.Invoice.ensureIndex( { LandlordId: 1 } );
db.Invoice.ensureIndex( { OwnerUserId: 1 } );
db.Invoice.ensureIndex( { DueDate: 1 } );
db.Invoice.ensureIndex( { AutoGenerated: 1 } );
但是,今天我注意到,当按 UserId、Type 和 TenantId(在一个查询中)进行过滤时,大约需要 750 毫秒。一旦我创建了以下索引:
db.Invoice.ensureIndex( { UserId: 1, Type: 1, TenantId: 1 } );
...查询开始耗时约 15 毫秒。很明显,当查询过滤多个字段(使用多个索引)时,在每个将被过滤的单独字段上创建索引是不高效的。但是,我不可能为将要执行的查询的每个排列创建索引。
解决办法是什么?我应该在每个可过滤字段上只有一个索引吗? (我得测试一下它的性能如何,但它似乎是错误的。)
【问题讨论】:
标签: c# mongodb mongodb-.net-driver