摆脱mongodb集合中的_id

ama*_*ouq 0 mongodb pymongo mongodb-query

我知道不可能删除_idmongodb集合中的字段.但是,我的集合的大小很大,该_id字段上的索引阻止我加载RAM中的其他索引.我的机器有125GB的RAM,我的收集统计数据如下:

 db.call_records.stats()
{
    "ns" : "stc_cdrs.call_records",
    "count" : 1825338618,
    "size" : 438081268320,
    "avgObjSize" : 240,
    "storageSize" : 468641284752,
    "numExtents" : 239,
    "nindexes" : 3,
    "lastExtentSize" : 2146426864,
    "paddingFactor" : 1,
    "systemFlags" : 0,
    "userFlags" : 1,
    "totalIndexSize" : 165290709024,
    "indexSizes" : {
        "_id_" : 73450862016,
        "caller_id_1" : 45919923504,
        "receiver_id_1" : 45919923504
    },
    "ok" : 1
}
Run Code Online (Sandbox Code Playgroud)

当我执行如下查询时:

db.call_records.find({ "$or" : [ { "caller_id": 125091840205 }, { "receiver_id" : 125091840205 } ] }).explain()
{
    "clauses" : [
        {
            "cursor" : "BtreeCursor caller_id_1",
            "isMultiKey" : false,
            "n" : 401,
            "nscannedObjects" : 401,
            "nscanned" : 401,
            "scanAndOrder" : false,
            "indexOnly" : false,
            "nChunkSkips" : 0,
            "indexBounds" : {
                "caller_id" : [
                    [
                        125091840205,
                        125091840205
                    ]
                ]
            }
        },
        {
            "cursor" : "BtreeCursor receiver_id_1",
            "isMultiKey" : false,
            "n" : 383,
            "nscannedObjects" : 383,
            "nscanned" : 383,
            "scanAndOrder" : false,
            "indexOnly" : false,
            "nChunkSkips" : 0,
            "indexBounds" : {
                "receiver_id" : [
                    [
                        125091840205,
                        125091840205
                    ]
                ]
Run Code Online (Sandbox Code Playgroud)

返回结果平均需要15秒以上.两个指数caller_idreceiver_id应该是90GB左右,这是确定.但是,73GB索引_id使得这个查询非常慢.

Sal*_*ali 5

您正确地告诉您无法_id从文档中删除字段.您也无法从此字段中删除索引,因此这是您必须要使用的内容.

出于某种原因,你首先假设_id索引使你的查询变慢,这是完全没有道理的,而且很可能是错误的.此索引未使用,只是保持不变.

在你的情况下我会尝试做的事情很少:

  • 您的收藏中有4000亿个文档,您是否认为现在是开始分片数据库的最佳时机?在我看来你应该.

  • 使用解释与您的查询实际找出减慢它的速度.

查看您的查询,我还会尝试执行以下操作:更改您的文档

{
  ... something else ...
  receiver_id: 234,
  caller_id: 342
}
Run Code Online (Sandbox Code Playgroud)

{
   ... something else ...
   participants: [342, 234]
}
Run Code Online (Sandbox Code Playgroud)

如果您的参与者[caller_id, receiver_id]按此顺序排列,那么您只能在此字段中放置一个索引.我知道它不会使你的索引变小,但我希望因为你不会使用$or子句,你会得到更快的结果.PS如果你这样做,不要在生产中这样做,测试它是否给你一个显着的改进,然后才改变产品.