Проблемы с Mon go и индексами в $ sort - PullRequest
0 голосов
/ 09 июля 2020

Я спрашиваю, как можно включить использование индекса для этапа $sort в пн go. Потому что он всегда выполняет COLLSCAN, а простой запрос требует времени (в моем случае 1 ') для выполнения.

EX: Если я запускаю db.data.distinct("doc.field"), это занимает меньше секунды, но если я запускаю

     {$sort:{"doc.field":1}} //this should use index and ease the $group stage
    ,{$group:{"_id":"$doc.field", "lbl":1}}
    ,{$group:{"lbl":1, "out":{$push:"$_id"} }} //slow also without this last grouping stage

Это примерно эквивалентно, это занимает больше минуты, моя база данных имеет около 5 ГБ данных, и это вызывает проблемы как с «разреженными», так и с «нормальными» индексами на 'do c .field'

Объяснение в первом запросе дает DISTINCT_SCAN и использует индекс, во втором - COLLSCAN и не использует индекс, даже если, согласно документам, он должен.

My запрос следующий:

db.getCollection('data').aggregate( 
[
//{$match:{'events.hi2.ClientId':{$exists:false}}},
{$sort:{'events.hi2.ClientId':1}},
    {
        "$group": {
            "_id": "$events.hi2.ClientId"
        }
    }]
,{allowDiskUse:true })

план запроса (с allPlansExecution) следующий:

{
    "stages" : [ 
        {
            "$cursor" : {
                "query" : {},
                "fields" : {
                    "events.hi2.ClientId" : 1,
                    "_id" : 0
                },
                "queryPlanner" : {
                    "plannerVersion" : 1,
                    "namespace" : "db.data",
                    "indexFilterSet" : false,
                    "parsedQuery" : {},
                    "queryHash" : "8B3D4AB8",
                    "planCacheKey" : "8B3D4AB8",
                    "winningPlan" : {
                        "stage" : "COLLSCAN",
                        "direction" : "forward"
                    },
                    "rejectedPlans" : []
                },
                "executionStats" : {
                    "executionSuccess" : true,
                    "nReturned" : 5147612,
                    "executionTimeMillis" : 54159,
                    "totalKeysExamined" : 0,
                    "totalDocsExamined" : 5147612,
                    "executionStages" : {
                        "stage" : "COLLSCAN",
                        "nReturned" : 5147612,
                        "executionTimeMillisEstimate" : 404,
                        "works" : 5147614,
                        "advanced" : 5147612,
                        "needTime" : 1,
                        "needYield" : 0,
                        "saveState" : 42826,
                        "restoreState" : 42826,
                        "isEOF" : 1,
                        "direction" : "forward",
                        "docsExamined" : 5147612
                    },
                    "allPlansExecution" : []
                }
            }
        }, 
        {
            "$sort" : {
                "sortKey" : {
                    "events.hi2.ClientId" : 1
                }
            }
        }, 
        {
            "$group" : {
                "_id" : "$events.hi2.ClientId"
            }
        }
    ],
    "ok" : 1.0
}

другой запрос:

db.data.distinct('events.hi2.ClientId');

и его план запроса (с allPlansExecution) таков:

{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "db.data",
        "indexFilterSet" : false,
        "parsedQuery" : {},
        "queryHash" : "03E96EE9",
        "planCacheKey" : "03E96EE9",
        "winningPlan" : {
            "stage" : "PROJECTION_DEFAULT",
            "transformBy" : {
                "_id" : 0,
                "events.hi2.ClientId" : 1
            },
            "inputStage" : {
                "stage" : "DISTINCT_SCAN",
                "keyPattern" : {
                    "events.hi2.ClientId" : 1
                },
                "indexName" : "ClientId",
                "isMultiKey" : true,
                "multiKeyPaths" : {
                    "events.hi2.ClientId" : [ 
                        "events"
                    ]
                },
                "isUnique" : false,
                "isSparse" : false,
                "isPartial" : false,
                "indexVersion" : 2,
                "direction" : "forward",
                "indexBounds" : {
                    "events.hi2.ClientId" : [ 
                        "[MinKey, MaxKey]"
                    ]
                }
            }
        },
        "rejectedPlans" : []
    },
    "executionStats" : {
        "executionSuccess" : true,
        "nReturned" : 201,
        "executionTimeMillis" : 3,
        "totalKeysExamined" : 201,
        "totalDocsExamined" : 0,
        "executionStages" : {
            "stage" : "PROJECTION_DEFAULT",
            "nReturned" : 201,
            "executionTimeMillisEstimate" : 0,
            "works" : 202,
            "advanced" : 201,
            "needTime" : 0,
            "needYield" : 0,
            "saveState" : 1,
            "restoreState" : 1,
            "isEOF" : 1,
            "transformBy" : {
                "_id" : 0,
                "events.hi2.ClientId" : 1
            },
            "inputStage" : {
                "stage" : "DISTINCT_SCAN",
                "nReturned" : 201,
                "executionTimeMillisEstimate" : 0,
                "works" : 202,
                "advanced" : 201,
                "needTime" : 0,
                "needYield" : 0,
                "saveState" : 1,
                "restoreState" : 1,
                "isEOF" : 1,
                "keyPattern" : {
                    "events.hi2.ClientId" : 1
                },
                "indexName" : "ClientId",
                "isMultiKey" : true,
                "multiKeyPaths" : {
                    "events.hi2.ClientId" : [ 
                        "events"
                    ]
                },
                "isUnique" : false,
                "isSparse" : false,
                "isPartial" : false,
                "indexVersion" : 2,
                "direction" : "forward",
                "indexBounds" : {
                    "events.hi2.ClientId" : [ 
                        "[MinKey, MaxKey]"
                    ]
                },
                "keysExamined" : 201
            }
        },
        "allPlansExecution" : []
    },
    
    "ok" : 1.0
}

1 Ответ

0 голосов
/ 11 июля 2020

Начиная с MongoDB v4.2:

Если конвейер сортирует и группирует по одному и тому же полю ... стадия $group может использовать индекс ... https://docs.mongodb.com/manual/reference/operator/aggregation/group/#optimization -to-return-the-first-document-of-each-group

db.getCollection('data').explain("allPlansExecution").aggregate([
  {"$sort":{'events.hi2.ClientId':1}}, // If you dont use `$first` operator,
                                       // you don't need to sort at all
  {
    "$group": {
        "_id": "$events.hi2.ClientId"
    }
  }
  ],{"allowDiskUse":true })

--- Вывод ---

{
    "stages" : [ 
        {
            "$cursor" : {
                "query" : {},
                "sort" : {
                    "events.hi2.ClientId" : 1
                },
                "fields" : {
                    "events.hi2.ClientId" : 1,
                    "_id" : 0
                },
                "queryPlanner" : {
                    "plannerVersion" : 1,
                    "namespace" : "test.data",
                    "indexFilterSet" : false,
                    "parsedQuery" : {},
                    "queryHash" : "14D2D195",
                    "planCacheKey" : "14D2D195",
                    "winningPlan" : {
                        "stage" : "PROJECTION_DEFAULT",
                        "transformBy" : {
                            "events.hi2.ClientId" : 1,
                            "_id" : 0
                        },
                        "inputStage" : {
                            "stage" : "DISTINCT_SCAN",
                            "keyPattern" : {
                                "events.hi2.ClientId" : 1.0
                            },
                            "indexName" : "events.hi2.ClientId_1",
                            "isMultiKey" : false,
                            "multiKeyPaths" : {
                                "events.hi2.ClientId" : []
                            },
                            "isUnique" : false,
                            "isSparse" : false,
                            "isPartial" : false,
                            "indexVersion" : 2,
                            "direction" : "forward",
                            "indexBounds" : {
                                "events.hi2.ClientId" : [ 
                                    "[MinKey, MaxKey]"
                                ]
                            }
                        }
                    },
                    "rejectedPlans" : []
                },
                "executionStats" : {
                    "executionSuccess" : true,
                    "nReturned" : 100000,
                    "executionTimeMillis" : 739,
                    "totalKeysExamined" : 100000,
                    "totalDocsExamined" : 0,
                    "executionStages" : {
                        "stage" : "PROJECTION_DEFAULT",
                        "nReturned" : 100000,
                        "executionTimeMillisEstimate" : 28,
                        "works" : 100001,
                        "advanced" : 100000,
                        "needTime" : 0,
                        "needYield" : 0,
                        "saveState" : 799,
                        "restoreState" : 799,
                        "isEOF" : 1,
                        "transformBy" : {
                            "events.hi2.ClientId" : 1,
                            "_id" : 0
                        },
                        "inputStage" : {
                            "stage" : "DISTINCT_SCAN",
                            "nReturned" : 100000,
                            "executionTimeMillisEstimate" : 15,
                            "works" : 100001,
                            "advanced" : 100000,
                            "needTime" : 0,
                            "needYield" : 0,
                            "saveState" : 799,
                            "restoreState" : 799,
                            "isEOF" : 1,
                            "keyPattern" : {
                                "events.hi2.ClientId" : 1.0
                            },
                            "indexName" : "events.hi2.ClientId_1",
                            "isMultiKey" : false,
                            "multiKeyPaths" : {
                                "events.hi2.ClientId" : []
                            },
                            "isUnique" : false,
                            "isSparse" : false,
                            "isPartial" : false,
                            "indexVersion" : 2,
                            "direction" : "forward",
                            "indexBounds" : {
                                "events.hi2.ClientId" : [ 
                                    "[MinKey, MaxKey]"
                                ]
                            },
                            "keysExamined" : 100000
                        }
                    },
                    "allPlansExecution" : []
                }
            }
        }, 
        {
            "$groupByDistinctScan" : {
                "newRoot" : {
                    "_id" : "$events.hi2.ClientId"
                }
            }
        }
    ],
    "serverInfo" : {
        ...
    },
    "ok" : 1.0
}
...