mongodb - 为什么 MongoDB 不使用索引交集?

标签 mongodb indexing database-indexes mongodb-indexes

我试图重现索引交集指令的第一个示例( http://docs.mongodb.org/manual/core/index-intersection/ ),但面临一个问题:mongo 不使用两个索引

我的步骤:

  1. 下载 mongo (3.0.3) 并安装
  2. 运行 mongod:mongod.exe --dbpath d:\data(文件夹为空)
  3. 运行 mongo:mongo.exe
  4. 添加索引:

    db.orders.ensureIndex({ qty: 1 })
    db.orders.ensureIndex({ item: 1 })
    db.orders.getIndexes()
    [{
            "v" : 1,
            "key" : {
                    "_id" : 1
            },
            "name" : "_id_",
            "ns" : "test.orders"
    },
    {
            "v" : 1,
            "key" : {
                    "qty" : 1
            },
            "name" : "qty_1",
            "ns" : "test.orders"
    },
    {
            "v" : 1,
            "key" : {
                    "item" : 1
            },
            "name" : "item_1",
            "ns" : "test.orders"
    }]
    
  5. 检查查询说明:

    db.orders.find( { item: "abc123", qty: { $gt: 15 } } ).explain()
    {
        "queryPlanner" : {
                "plannerVersion" : 1,
                "namespace" : "test.orders",
                "indexFilterSet" : false,
                "parsedQuery" : {
                        "$and" : [
                                {
                                        "item" : {
                                                "$eq" : "abc123"
                                        }
                                },
                                {
                                        "qty" : {
                                                "$gt" : 15
                                        }
                                }
                        ]
                },
                "winningPlan" : {
                        "stage" : "KEEP_MUTATIONS",
                        "inputStage" : {
                                "stage" : "FETCH",
                                "filter" : {
                                        "qty" : {
                                                "$gt" : 15
                                        }
                                },
                                "inputStage" : {
                                        "stage" : "IXSCAN",
                                        "keyPattern" : {
                                                "item" : 1
                                        },
                                        "indexName" : "item_1",
                                        "isMultiKey" : false,
                                        "direction" : "forward",
                                        "indexBounds" : {
                                                "item" : [
                                                        "[\"abc123\", \"abc123\"]"
                                                ]
                                        }
                                }
                        }
                },
                "rejectedPlans" : [
                        {
                                "stage" : "KEEP_MUTATIONS",
                                "inputStage" : {
                                        "stage" : "FETCH",
                                        "filter" : {
                                                "item" : {
                                                        "$eq" : "abc123"
                                                }
                                        },
                                        "inputStage" : {
                                                "stage" : "IXSCAN",
                                                "keyPattern" : {
                                                        "qty" : 1
                                                },
                                                "indexName" : "qty_1",
                                                "isMultiKey" : false,
                                                "direction" : "forward",
                                                "indexBounds" : {
                                                        "qty" : [
                                                                "(15.0, 1.#INF]"
                                                        ]
                                                }
                                        }
                                }
                        }
                ]
        },
        "serverInfo" : {
                "host" : "localhost",
                "port" : 27017,
                "version" : "3.0.3",
                "gitVersion" : "b40106b36eecd1b4407eb1ad1af6bc60593c6105"
        },
        "ok" : 1
    }
    

如您所见,winingPlan 仅包含 item_1 索引。有一个包含 qty_1 索引的rejectedPlans。但没有包含索引交集的计划。 我知道选择特定索引有很多条件。但就我而言,mongo 甚至没有计划它!

有人可以帮助我吗?

最佳答案

SERVER-3071 JIRA issue中有一些关于索引选择的详细信息。但我不能说所有内容是否仍然与 3.0 相关。无论如何:

MongoDB 3.0.2似乎不考虑范围查询的索引交互。但它会针对点间隔:

> db.orders.find( { item: {$eq : "abc123"}, qty: { $eq: 15 } } ).explain()
...

        {
            "stage" : "FETCH",
            "inputStage" : {
                "stage" : "KEEP_MUTATIONS",
                "inputStage" : {
                    "stage" : "AND_SORTED",
                    "inputStages" : [
                        {
                            "stage" : "IXSCAN",
                            "keyPattern" : {
                                "qty" : 1
                            },
                            "indexName" : "qty_1",
                            "isMultiKey" : false,
                            "direction" : "forward",
                            "indexBounds" : {
                                "qty" : [
                                    "[15.0, 15.0]"
                                ]
                            }
                        },
                        {
                            "stage" : "IXSCAN",
                            "keyPattern" : {
                                "item" : 1
                            },
                            "indexName" : "item_1",
                            "isMultiKey" : false,
                            "direction" : "forward",
                            "indexBounds" : {
                                "item" : [
                                    "[\"abc123\", \"abc123\"]"
                                ]
                            }
                        }
                    ]
                }

关于mongodb - 为什么 MongoDB 不使用索引交集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30626726/

相关文章:

java - 项目正在寻找数据源,但我正在使用 MongoDB

mysql - 在 mysql 中更新触发器后触发并将该数据插入 mongodb

MySQL - 使用聚合函数加速查询的索引

mysql - 如何优化 MySQL 数据库/查询

node.js - node js 同时使用 Mongodb 和 Redis

java - 从mongodb中提取特定字段

mysql - 通过 MySQL 上的 EXPLAIN 查询分析需要改进的内容

python - 根据另一个字符串向字符串添加符号

c# - 为MySQL中的所有列创建索引

sql - 在只有 2 个不同值的列上创建索引