Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/249.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php MongoDB中的索引如何降低查询速度?_Php_Mongodb - Fatal编程技术网

Php MongoDB中的索引如何降低查询速度?

Php MongoDB中的索引如何降低查询速度?,php,mongodb,Php,Mongodb,** 更新 ** 我发布了一个答案,因为它已经被证实是一个问题 ** 起初的 ** 首先,我道歉——我昨天刚开始使用MongoDB,我对这一点还很陌生。我有一个非常简单的查询,使用PHP我的发现如下: Mongo版本为2.0.4,在CentOS 6.2(最终版)x64上运行 如果没有索引,则返回: Query lasted 0.15 seconds 我在数据库里有280000条记录。因此,我认为在“items”上添加索引应该会有所帮助,因为我经常查询这些数据。但令我难以置信的是,在添加索引后,

** 更新 **

我发布了一个答案,因为它已经被证实是一个问题

** 起初的 **

首先,我道歉——我昨天刚开始使用MongoDB,我对这一点还很陌生。我有一个非常简单的查询,使用PHP我的发现如下:

Mongo版本为2.0.4,在CentOS 6.2(最终版)x64上运行

如果没有索引,则返回:

Query lasted 0.15 seconds
我在数据库里有280000条记录。因此,我认为在“items”上添加索引应该会有所帮助,因为我经常查询这些数据。但令我难以置信的是,在添加索引后,我得到了以下结果:

Query lasted 0.25 seconds
我做错什么了吗

我用find代替count得到解释,这是输出:

> db.people.find({ 'items' : { '$gte' : 1 } }).explain();
{
"cursor" : "BtreeCursor items_1",
"nscanned" : 206396,
"nscannedObjects" : 206396,
"n" : 206396,
"millis" : 269,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
    "items" : [
        [
            1,
            1.7976931348623157e+308
        ]
    ]
}
}
如果我将查询更改为“$ne”0,则需要10毫秒以上

以下是收集数据:

> db.people.stats()
{
"ns" : "stats.people",
"count" : 281207,
"size" : 23621416,
"avgObjSize" : 84.00009957077881,
"storageSize" : 33333248,
"numExtents" : 8,
"nindexes" : 2,
"lastExtentSize" : 12083200,
"paddingFactor" : 1,
"flags" : 0,
"totalIndexSize" : 21412944,
"indexSizes" : {
    "_id_" : 14324352,
    "items_1" : 7088592
},
"ok" : 1
}
我有1GB的内存可用,所以我相信索引适合内存

以下是所要求的人员索引:

> db.people.getIndexes()
[
{
    "v" : 1,
    "key" : {
        "_id" : 1
    },
    "ns" : "stats.people",
    "name" : "_id_"
},
{
    "v" : 1,
    "key" : {
        "items" : 1
    },
    "ns" : "stats.people",
    "name" : "items_1"
}
]

拥有索引有两个好处:

  • 仅访问集合的一小部分时(因为索引可以满足限制性筛选器)。经验法则不到10%

  • 当完全不需要访问集合时(因为所有必要的数据都在索引中,用于筛选和结果集)。这将由“indexOnly=true”表示

  • 对于“find”查询,这两种情况都不是真的:您访问的几乎是整个集合(281207个集合中的206396个),并且需要所有字段数据。因此,您将首先遍历索引,然后遍历几乎整个集合,这违背了索引的目的。只要阅读整个收藏就会更快

    我希望“count”查询的性能会更好(因为只需遍历索引就可以满足这一要求)。你也能解释一下吗?

    看看这个:

    这使我考虑了这个解决办法。这个怎么样

    $totalactive = $db->people->count() - $db->people->count(array('items'=> array('$eq' => 1)));
    

    请提供此集合中对象的示例,好吗?“项目”字段是数组吗?如果是这样的话,我建议您添加一个新字段“itemCount”,并在其上添加一个索引。在该字段上执行$gt将非常快。

    这是因为您的查询接近完整集合扫描。查询优化器正在选择使用索引,而不应该使用它来获得最佳性能。这是违反直觉的,是的,但这是因为光标正在遍历索引b树并获取树指向的文档,如果它必须扫描几乎整个树,这比遍历集合要慢

    如果确实需要执行此类查询,并且希望将该索引用于其他事情,如排序,则可以使用
    .hint({$natural:1})
    ,告诉查询不要使用该索引


    巧合的是,我最近在一篇博客文章中发布了一个类似的问题:

    这被证实是一个bug或MongoDB引擎中需要优化的东西。我在mongo邮件列表和Eliot Horowitz的回复中发布了这个消息

    这肯定是一个bug,或者至少是一条更好的路径 优化。提出理由:


    感谢那些帮助确认这是一个bug=)

    这真的很有趣。尝试使用linux
    time
    命令来计时多个迭代。您使用的是哪个版本的MongoDB?似乎“count”目前并没有它所能做到的那么聪明:您能给我们提供
    db.people.getIndexes()的输出吗
    ?@NicholasTolleyCottrell添加了索引。您无法对计数进行解释。必须有一种方法。。。我会问:我很喜欢你的解释,但在这种情况下,只应使用索引(用于计数)——我尝试进行查找,只指定“items”作为返回字段,但它仍然以索引形式显示为false。@rainernix:是的,计数应该使用索引。您是只返回项目还是同时返回_id?如果我使用find specify不返回_id并且只返回项目,说明会显示仅使用索引,但仍然比使用计数慢。这肯定更快。对于相同的结果,我得到的是0.09ms,而不是0.25ms/0.35ms。不过,如果有此索引,Count($gt:1)通常应该比Count()快。该索引中是否存在大量数据倾斜(即大多数数据为0或1)?如果您指的是链接到的文档,它们谈论的是$nin和$ne,而不是$gt(没有此问题)。也许这是10gen的问题。我刚刚参加了一个由他们的纽约开发者主持的技术讲座,我会给他发一封电子邮件。我实际上使用了:$db->people->count(array('items'=>0))和上面发布的内容,这就是我获得更快响应的原因。在php中数到280000只需要0.03秒——考虑到它已被索引,我仍然相信我应该期待更快的响应,但这是朝着正确方向迈出的一步。项是一个数字,集合非常小。它类似于:{“slots”:50,“last_update”:1334325643,{u id:“128713871987491”,“items”:0}我将我的发现发布在mongo邮件列表上,Eliot(10gen的首席技术官)回答说这确实是一个bug,或者需要优化。它被添加为一个主要问题:--我将结束这个问题。
    $totalactive = $db->people->count() - $db->people->count(array('items'=> array('$eq' => 1)));
    
    Priority:  Major
    Fix Version/s: 2.3 desired
    Type:  Bug