Mongodb 如何加速使用多个字符串过滤器的查询?
我在MongoDB 3.4中有一个集合,用于存储来自某个应用程序的所有用户的联系人。每个联系人都有一个大的字符串字段列表(100+)。我使用MongoDB,但这个问题对于任何其他引擎(MySQL、弹性搜索等)都是有效的 几乎所有检索联系人的查询都有相同的四个基本条件,例如,user_id、base_field1、base_field2、base_field3,因此我用这些字段创建了一个复合索引以改进查询。基本查询如下所示:Mongodb 如何加速使用多个字符串过滤器的查询?,mongodb,Mongodb,我在MongoDB 3.4中有一个集合,用于存储来自某个应用程序的所有用户的联系人。每个联系人都有一个大的字符串字段列表(100+)。我使用MongoDB,但这个问题对于任何其他引擎(MySQL、弹性搜索等)都是有效的 几乎所有检索联系人的查询都有相同的四个基本条件,例如,user_id、base_field1、base_field2、base_field3,因此我用这些字段创建了一个复合索引以改进查询。基本查询如下所示: db.contacts.find({ user_id: 1434
db.contacts.find({
user_id: 1434,
base_field1: {$in: [0, 10]},
base_field2: true,
base_field3: "some value"
}).limit(10)
基本查询的执行时间很好(少于2秒),但请记住,有25K个联系人与基本条件匹配
但是,该应用程序允许用户按任何其他字段筛选联系人,甚至添加任意数量的筛选器。所有过滤器都使用contains运算符,因此查询如下所示:
db.contacts.find({
user_id: 1434,
base_field1: {$in: [0, 10]},
base_field2: true,
base_field3: "some value",
field4: {$regex: "foobar", $options: "i"},
field5: {$regex: "foobar", $options: "i"},
field6: {$regex: "foobar", $options: "i"},
.
.
.
}).limit(10)
因此,执行时间不适合我们的要求(在9-10秒之间)。此外,正如您所料,增加过滤器的数量也会增加执行时间,因此:
从设计和查询的角度来看,有没有办法加快查询速度?
还有比MongoDB更好的数据库引擎来改进这种查询吗?
在答复之前,请考虑以下意见和限制:
- 文本索引在这里是无用的,因为如果我创建了一个包含所有可能字段的复合文本索引,但用户仅按字段4筛选包含“foobar”,那么结果可能会有字段5中包含“foobar”的联系人
- 只需创建一个化合物
- 为每个字段创建一个简单的索引没有意义,因为当用户按多个字段筛选时,MongoDB只会使用一个索引。您还可以创建
- 实际上,我通过散列键(user_id)使用MongoDB共享集群,但为了简化,我将问题缩小到只有一个shard的范围,我的意思是,即使我为每个用户添加一个shard,问题仍然存在
编辑:我更改了条件(字段4或字段5…)以及真实情况下的条件。MySQL在哪里起作用?我正在删除这个标签,因为您似乎正在搜索MongoDB答案。我认为您的假设“我使用MongoDB,但这个问题对任何其他引擎都有效”是不正确的。每个引擎可以有不同的性能基准,这取决于它存储/索引数据的方式。我正在删除
elasticsearch
标记,因为这与MongoDB相关。你能确定哪64个是最常用的搜索字段,并为每个字段添加索引吗?@Val我在MySQL中回答了这个问题,问题也是一样的。执行时间显然有点不同,但原理是一样的:添加的过滤器越多,查询速度就越慢。我认为这是一个常见的问题,无论您使用什么DB引擎,这就是为什么我将问题扩展到其他引擎,尽管我使用MongoDB。也许其他引擎的一些经验(索引、文本搜索、查询等)可以应用于MongoDB。MySQL在哪里起作用?我正在删除这个标签,因为您似乎正在搜索MongoDB答案。我认为您的假设“我使用MongoDB,但这个问题对任何其他引擎都有效”是不正确的。每个引擎可以有不同的性能基准,这取决于它存储/索引数据的方式。我正在删除elasticsearch
标记,因为这与MongoDB相关。你能确定哪64个是最常用的搜索字段,并为每个字段添加索引吗?@Val我在MySQL中回答了这个问题,问题也是一样的。执行时间显然有点不同,但原理是一样的:添加的过滤器越多,查询速度就越慢。我认为这是一个常见的问题,无论您使用什么DB引擎,这就是为什么我将问题扩展到其他引擎,尽管我使用MongoDB。也许其他引擎的一些经验(索引、文本搜索、查询等)可以应用于MongoDB。