过滤和排序以下哪个查询将使用索引?

Posted

技术标签:

【中文标题】过滤和排序以下哪个查询将使用索引?【英文标题】:Both Filtering & Sorting Which of following queries will use index? 【发布时间】:2017-02-28 06:50:50 【问题描述】:

有一个集合people,其索引如下:

"first_name": 1, "address.state": -1, "address.city": -1, "ssn": 1

对于过滤和排序, 以下哪个查询将使用索引?

    "first_name": $gt: "J" ).sort( "address.city": -1 "first_name": "Jessica" ).sort( "address.state": 1, "address.city": 1 "first_name": "Jessica", "address.state": $lt: "S" ).sort( "address.state": 1 "address.city":"West Cindy").sort( "address.city":-1 "address.state":"South Dakota","first_name": "Jessica").sort( "address.city":-1

我已经完成了以下问题: Which of the following queries will use the index?

但它只解释了过滤的索引,我需要对过滤器和排序功能都使用索引。

另外,我如何确定索引是否同时用于过滤和排序 或者没用过?

【问题讨论】:

添加.explain(); explain 会告诉您索引的使用位置,但作为 B-Tree 索引的 tumb 规则,它们将从索引中的第一项开始从左到右工作。您可以查看有关 B-tree 索引的官方 wiki 文章 here。对于排序也很重要索引的方向(ASC 或 DESC) @Dan Ionescu,复合索引从左到右(不是从右到左)。所以复合索引的第一个字段可以直接使用,而不是第二个... 【参考方案1】:

Mongo 使用左侧的索引,即"first_name": 1, "address.state": -1, "address.city": -1, "ssn": 1 索引可以应用于以下字段查询-

“first_name”:1,“address.state”:-1,“address.city”:-1,“ssn”:1 “first_name”:1,“address.state”:-1,“address.city”:-1 "first_name": 1, "address.state": -1 "first_name": 1

还应注意,顺序对于复合索引很重要。

说到问题,我知道这是 M201 课程 Lab 2.1 的作业问题,所以我很了解数据集。我将逐个选择选项-

    "first_name": $gt: "J" ).sort( "address.city": -1 不能选择,因为排序是在地址城市,所以不能乱序使用索引。

    "first_name": "Jessica" ).sort( "address.state": 1, "address.city": 1 可以是一个选项。为确保这一点,我们需要运行以下查询-

    var ex = db.people.explain();
    ex.find( "first_name": "Jessica" ).sort( "address.state": 1, "address.city": 1 )
    

上面的查询返回一个没有类似 "stage" : "SORT" 的响应,它告诉我们在 DB 中使用索引进行了排序。如果我们有 Stage SORT,那么它表明排序发生在 RAM 中,而 DB 无法使用索引在数据库中进行排序。

    "first_name": "Jessica", "address.state": $lt: "S" ).sort( "address.state": 1 我和选项2一样。

    ex.find( "first_name": "Jessica", "address.state": $lt: "S" ).sort( "address.state": 1 ) 上面的输出没有任何 SORT 阶段表明 DB 能够使用索引进行排序。

    "address.city":"West Cindy").sort( "address.city":-1忽略这个,因为索引不是从左边开始的。

    "address.state":"South Dakota","first_name": "Jessica").sort( "address.city":-1 这与选项 2 相同。我执行了类似的查询,但没有得到任何 SORT 阶段,因此它使用索引进行排序。

使用索引进行过滤非常容易识别。如果ex.find(<Your query>) 给出一个 "stage" : "COLLSCAN" 则索引不用于过滤。选项 2、3、5 在 ex.find() 响应中没有 "stage" : "COLLSCAN",因此这些使用索引进行过滤。

这样我确保所有选项都使用索引进行过滤和排序。

您也可以为选项 1 和 4 运行 ex.find(),您将得到 "stage" : "COLLSCAN" 或 "stage" : "SORT",这表明索引未分别用于过滤或排序。

谢谢...

【讨论】:

以上是关于过滤和排序以下哪个查询将使用索引?的主要内容,如果未能解决你的问题,请参考以下文章

使用 numpy 从过滤后的排序数组返回索引

短语查询和使用 shingle 过滤器有啥区别?

SOLR查询过滤结果中的自定义排序?

如何在Elasticsearch中过滤或查询索引名称列表?

Oracle数据库--过滤和排序

MongoDB通过许多参数过滤(复合索引与否)