Php MongoDB的性能各不相同

Php MongoDB的性能各不相同,php,performance,mongodb,Php,Performance,Mongodb,我有这样一个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",

我有这样一个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 Ram(mongo使用7),Windows 7索引不能用于不区分大小写的正则表达式查询,也不能用于非根正则表达式(那些不是以“
^
”开头的)。由于您已经将
A2_Firstname
字段反规范化为
A2_FirstnameC
,因此您还可以存储规范化的字段大小写(即所有小写或所有大写),并避免使用不区分大小写的正则表达式;但是,即使在这种情况下,如果不使用根正则表达式,您仍将对集合进行完整扫描。在这种情况下,您是否能够负担得起使用索引取决于您的具体用例。

索引不能用于不区分大小写的正则表达式查询,也不能用于非根正则表达式(那些不是以“
^
开头的正则表达式)。由于您已经将
A2_Firstname
字段反规范化为
A2_FirstnameC
,因此您还可以存储规范化的字段大小写(即所有小写或所有大写),并避免使用不区分大小写的正则表达式;但是,即使在这种情况下,如果不使用根正则表达式,您仍将对集合进行完整扫描。在这种情况下,您是否可以使用索引取决于您的具体用例。

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


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

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


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

“/^jose/”和“/jose/”查询在我的集合上占用相同的时间。有什么想法吗?@Stefan,在某些情况下是真的。你能显示
explain()
输出吗?我明天会做。现在,我重新检查了我的需求,希望通过索引数组“^jose/”和“/jose/”查询在我的集合上实现您的方式。有什么想法吗?@Stefan,在某些情况下是真的。你能显示
explain()
输出吗?我明天会做。现在,我重新检查了我的需求,希望用索引数组实现您的方法