【问题标题】:MongoDB performance variesMongoDB 性能各不相同
【发布时间】:2011-11-30 20:57:13
【问题描述】:

我有一个这样的 mongo 集合:


{
"A2_AboutMe": "",
"A2_Attributes": "|av|nv|",
"A2_Birthday": "",
"A2_DateCreated": "2010-11-25 22: 59: 00",
"A2_DateLast": "2011-11-18 12: 09: 36",
"A2_FK_A1_IDPerson": "0",
"A2_Firstname": "José Luis",
"A2_FirstnameC": "Jose Luis",
"A2_Gender": "m",
"A2_IDProfile": "1",
"A2_Keywords": "...|..",
"A2_Lastname": "test - test",
"A2_LastnameC": "_test test",
"A2_Locale": "",
"A2_Middlename": "",
"A2_Name": "José Luis test",
"A2_NameC": "Jose Luis test",
...
}

在 A2_LastnameC 和 A2_FirstnameC 上有索引 此集合中有 3.000.000 个文档,8 GB 数据存储

以下查询 (PHP) 在 3-4 秒内完成

$collection->find(array(«A2_FirstnameC» => new MongoRegex("/jose/i")))->sort(array(«A2_LastnameC» => -1))->limit(10)

但有时类似的查询会在不到 100 毫秒的时间内完成。

我可以怎样做才能每次都获得这种性能?

测试计算机是 i7,8GB 内存(mongo 使用 7),Windows 7

【问题讨论】:

    标签: php performance mongodb


    【解决方案1】:

    首先,索引不会用于非前缀、不区分大小写的正则表达式。但在上面的查询中,索引可用于按A2_LastnameC 字段排序,因此速度很快。现在有了排序后的数据,MongoDB 将需要获取 A2_FirstnameC 值并将其与 10 个匹配项准备好时停止的正则表达式进行匹配(它也会相对较快,因为它将使用索引来检索数据而不是从磁盘读取整个文档) .根据数据顺序,它可能恰好匹配前 10 个文档 - 这是最好的情况,它会非常快,最坏的情况是在最后 10 个文档上发生的匹配必须扫描所有以前的索引条目。

    如何加快速度?要么使用可以使用索引的查询,例如:«A2_FirstnameC» => new MongoRegex("/^jose/")。或者您必须使用某种全文搜索。一种简单的方法是将字段(在您的情况下为A2_Firstname)拆分为单词,将它们标准化(转换为小写,替换重音)并存储为数组。现在将使用数组字段的索引进行快速搜索。

    【讨论】:

    • "/^jose/" 和 "/jose/" 查询在我的收藏中花费了相同的时间。有什么想法吗?
    • @Stefan 在某些情况下可能是真的。你能显示explain() 输出吗?
    • 我明天会做的。现在我重新检查了我的要求,并希望用索引数组实现你的方式
    【解决方案2】:

    索引不能用于不区分大小写的正则表达式查询,也不能用于无根正则表达式(不以“^”开头的)。由于您已经将A2_Firstname 字段非规范化为A2_FirstnameC,因此您还可以将该字段大小写规范化(即全部小写或全部大写),并避免使用不区分大小写的正则表达式;但是,即使在这种情况下,如果您不使用有根正则表达式,您仍将对集合进行全面扫描。在这种情况下您是否负担得起使用一个取决于您的确切用例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-13
      • 2021-12-27
      相关资源
      最近更新 更多