Что такое multiKeyPaths в объяснении, и почему отсутствие этого приводит к неправильному использованию индекса

У меня есть большая коллекция с 4 осколками.

Когда я запускаю запрос к индексируемому массиву, поле "array.number" выглядит так:

var query = { "array" : { $elemMatch: { "number" : { $gte : "10", $lt : "20" } } } };

и проверить explainЯ получу эти планы на выигрыш (сокращенно для ясности):

Осколки 0/2/3:

"inputStage": {
  "stage": "IXSCAN",
  ...
  "isMultiKey": true,
  "indexBounds": {
    "array.number": [
      "[\"10\", {})"
    ]
  }
}

Shard1:

"inputStage": {
  "stage": "IXSCAN",
  ...
  "isMultiKey": true,
  "multiKeyPaths": {
    "array.number": [
      "array"
    ]
  },
  "indexBounds": {
    "array.number": [
      "[\"10\", \"20\")"
    ]
  }
}

Таким образом, shard1 дает ожидаемое оптимальное использование индекса, ограничивая inputStage только 10-20, в то время как другие сегменты используют только нижнюю границу индекса. Единственная разница между осколками объектов multiKeyPaths часть, которая отсутствует в осколках 0/2/3.

Любая идея, почему это так, и как мы можем заставить другие наши шарды правильно использовать наш индекс?

ОБНОВИТЬ

Вот полный ответ объяснения для следующего запроса:

var query = { "array" : { $elemMatch: { "number" : { $gte : "10", $lt : "20" } } } };
db.collection.find(query).explain()

Отклик:

{
    "queryPlanner" : {
        "mongosPlannerVersion" : 1,
        "winningPlan" : {
            "stage" : "SHARD_MERGE",
            "shards" : [ 
                {
                    "shardName" : "company_rs0",
                    "connectionString" : "company_rs0/shard0-db0:27017,shard0-db1:27017",
                    "serverInfo" : {"host":"shard0-db0","port":27017,"version":"3.4.7","gitVersion":"cf38c1b8a0a8dca4a11737581beafef4fe120bcd"},
                    "plannerVersion" : 1,
                    "namespace" : "company_database.collection",
                    "indexFilterSet" : false,
                    "parsedQuery" : {"array":{"$elemMatch":{"$and":[{"number":{"$lt":"20"}},{"number":{"$gte":"10"}}]}}},
                    "winningPlan" : {
                        "stage" : "FETCH",
                        "filter" : {
                            "array" : {
                                "$elemMatch" : {"$and":[{"number":{"$gte":"10"}},{"number":{"$lt":"20"}}]}
                            }
                        },
                        "inputStage" : {
                            "stage" : "IXSCAN",
                            "numberPattern" : {"array.number":1.0},
                            "indexName" : "array.number_1",
                            "isMultiKey" : true,
                            "isUnique" : false,
                            "isSparse" : false,
                            "isPartial" : false,
                            "indexVersion" : 1,
                            "direction" : "forward",
                            "indexBounds" : {"array.number":["[\"10\", {})"]}
                        }
                    },
                    "rejectedPlans" : [ 
                        {
                            "stage" : "FETCH",
                            "filter" : {
                                "array" : {"$elemMatch":{"$and":[{"number":{"$lt":"20"}},{"number":{"$gte":"10"}}]}}
                            },
                            "inputStage" : {
                                "stage" : "IXSCAN",
                                "numberPattern" : {"array.number":1.0},
                                "indexName" : "array.number_1",
                                "isMultiKey" : true,
                                "isUnique" : false,
                                "isSparse" : false,
                                "isPartial" : false,
                                "indexVersion" : 1,
                                "direction" : "forward",
                                "indexBounds" : {"array.number":["[\"\", \"20\")"]}
                            }
                        }
                    ]
                }, 
                {
                    "shardName" : "company_rs1",
                    "connectionString" : "company_rs1/shard1-db0:27017,shard1-db1:27017",
                    "serverInfo" : {"host":"shard1-db0","port":27017,"version":"3.4.7","gitVersion":"cf38c1b8a0a8dca4a11737581beafef4fe120bcd"},
                    "plannerVersion" : 1,
                    "namespace" : "company_database.collection",
                    "indexFilterSet" : false,
                    "parsedQuery" : {
                        "array" : {"$elemMatch":{"$and":[{"number":{"$lt":"20"}},{"number":{"$gte":"10"}}]}}
                    },
                    "winningPlan" : {
                        "stage" : "FETCH",
                        "filter" : {
                            "array" : {"$elemMatch":{"$and":[{"number":{"$lt":"20"}},{"number":{"$gte":"10"}}]}}
                        },
                        "inputStage" : {
                            "stage" : "IXSCAN",
                            "numberPattern" : {"array.number":1.0},
                            "indexName" : "array.number_1",
                            "isMultiKey" : true,
                            "multiKeyPaths" : {"array.number":["array"]},
                            "isUnique" : false,
                            "isSparse" : false,
                            "isPartial" : false,
                            "indexVersion" : 1,
                            "direction" : "forward",
                            "indexBounds" : {"array.number":["[\"10\", \"20\")"]}
                        }
                    },
                    "rejectedPlans" : []
                }, 
                {
                    "shardName" : "company_rs2",
                    "connectionString" : "company_rs2/shard2-db0:27017,shard2-db1:27017",
                    "serverInfo" : {"host":"shard2-db0","port":27017,"version":"3.4.7","gitVersion":"cf38c1b8a0a8dca4a11737581beafef4fe120bcd"},
                    "plannerVersion" : 1,
                    "namespace" : "company_database.collection",
                    "indexFilterSet" : false,
                    "parsedQuery" : {
                        "array" : {"$elemMatch":{"$and":[{"number":{"$lt":"20"}},{"number":{"$gte":"10"}}]}}
                    },
                    "winningPlan" : {
                        "stage" : "FETCH",
                        "filter" : {
                            "array" : {"$elemMatch":{"$and":[{"number":{"$gte":"10"}},{"number":{"$lt":"20"}}]}}
                        },
                        "inputStage" : {
                            "stage" : "IXSCAN",
                            "numberPattern" : {"array.number":1.0},
                            "indexName" : "array.number_1",
                            "isMultiKey" : true,
                            "isUnique" : false,
                            "isSparse" : false,
                            "isPartial" : false,
                            "indexVersion" : 1,
                            "direction" : "forward",
                            "indexBounds" : {"array.number":["[\"10\", {})"]}
                        }
                    },
                    "rejectedPlans" : [ 
                        {
                            "stage" : "FETCH",
                            "filter" : {
                                "array" : {"$elemMatch":{"$and":[{"number":{"$lt":"20"}},{"number":{"$gte":"10"}}]}}
                            },
                            "inputStage" : {
                                "stage" : "IXSCAN",
                                "numberPattern" : {"array.number":1.0},
                                "indexName" : "array.number_1",
                                "isMultiKey" : true,
                                "isUnique" : false,
                                "isSparse" : false,
                                "isPartial" : false,
                                "indexVersion" : 1,
                                "direction" : "forward",
                                "indexBounds" : {"array.number":["[\"\", \"20\")"]}
                            }
                        }
                    ]
                }, 
                {
                    "shardName" : "company_rs3",
                    "connectionString" : "company_rs3/shard3-db0:27017,shard3-db1:27017",
                    "serverInfo" : {"host":"shard3-db0","port":27017,"version":"3.4.7","gitVersion":"cf38c1b8a0a8dca4a11737581beafef4fe120bcd"},
                    "plannerVersion" : 1,
                    "namespace" : "company_database.collection",
                    "indexFilterSet" : false,
                    "parsedQuery" : {
                        "array" : {"$elemMatch":{"$and":[{"number":{"$lt":"20"}},{"number":{"$gte":"10"}}]}}
                    },
                    "winningPlan" : {
                        "stage" : "FETCH",
                        "filter" : {
                            "array" : {"$elemMatch":{"$and":[{"number":{"$gte":"10"}},{"number":{"$lt":"20"}}]}}
                        },
                        "inputStage" : {
                            "stage" : "IXSCAN",
                            "numberPattern" : {"array.number":1.0},
                            "indexName" : "array.number_1",
                            "isMultiKey" : true,
                            "isUnique" : false,
                            "isSparse" : false,
                            "isPartial" : false,
                            "indexVersion" : 1,
                            "direction" : "forward",
                            "indexBounds" : {"array.number":["[\"10\", {})"]}
                        }
                    },
                    "rejectedPlans" : [ 
                        {
                            "stage" : "FETCH",
                            "filter" : {
                                "array" : {"$elemMatch":{"$and":[{"number":{"$lt":"20"}},{"number":{"$gte":"10"}}]}}
                            },
                            "inputStage" : {
                                "stage" : "IXSCAN",
                                "numberPattern" : {"array.number":1.0},
                                "indexName" : "array.number_1",
                                "isMultiKey" : true,
                                "isUnique" : false,
                                "isSparse" : false,
                                "isPartial" : false,
                                "indexVersion" : 1,
                                "direction" : "forward",
                                "indexBounds" : {"array.number":["[\"\", \"20\")"]}
                            }
                        }
                    ]
                }
            ]
        }
    },
    "ok" : 1.0
}

0 ответов

Другие вопросы по тегам