mongodb创建索引(mongodb创建索引阻塞)

本篇文章给大家谈谈mongodb创建索引,以及mongodb创建索引阻塞对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

mongodb文本搜索

这几天做app,绕不开搜索,在没有看mongodb文档的情况下,胡思乱想了半个小时该怎么处理文本搜索,没想到官网对于文本搜索有非常详尽的说明,不看官方文档的码农就是少根筋。本文基本按照 官网的文本搜索 部分翻译,如有错,请各位批评指正!

要在mongodb中使用文本搜索,必须使用text索引和$text操作,下面的例子演示了如何创建text索引并且用它进行文本搜索。假设collection存储的数据如下例所示:

在mongodb中做文本搜索,必须要创建文本索引。文本索引建立在collection上,一个collection最多只能建立一个文本索引,文本索引可以cover多个域。如要在上例中的name和description中搜索文本,则可建立文本索引:

在建立文本索引的基础上,我们可以实施文本操作,如下例在name和description中寻找包括java或coffee或shop的文档,这里的$text表示或操作。

当然,也有更精确的搜索操作,如下例中精确寻找包含java或coffee shop的文档

mongodb还提供了排除好敬操作,如下例中的寻找包含java或coffee,但不包括coffee的文档

在很多情况下,我们需要对搜索的结果进行排序,mongodb也为我们提供了这种排序机制,如下例中所示

其实,mongodb对于一般的app中的搜索而言已经足够,在并发度不高的情况下,直接使用即可。如果并发度偏高,可以借助缓存的形式,对常用的搜索关镇让键字,在内存友旅慎中建立到排表,提升访问效率。

[img]

mongo数据库是怎么创建索引

2种方式:

(1)mongo shell

db.yourCollectionName.createIndex({fieldName: 1})

举例:

db.gameShortLink.createIndex({shortLink: 1})

(2)pymongo代码

 乎旦厅     indexKeyList = [

("fieldName", pymongo.ASCENDING),

]

mongoCollection.create_index(indexKeyList)

注:

一次性创建多个索引,举例:迟者

import pymongo

from pymongo import IndexModel

# from pymongo import ASCENDING, DESCENDING

indexShortLink = IndexModel([("shortLink", pymongo.ASCENDING)], name="shortLink")

indexIsParseOk = IndexModel([("parsedLink.isParseOk", pymongo.ASCENDING)], name="parsedLink_isParseOk")

indexErrType = IndexModel([("parsedLink.errType", pymongo.ASCENDING)], name="parsedLink_errType")

indexRealGameName = IndexModel([("parsedGame.realGameName", pymongo.ASCENDING)], name="parsedGame_realGameName")

indexGameTheme = IndexModel([("parsedGame.gameTheme", pymongo.ASCENDING)], name="parsedGame_gameTheme")

indexModelList = [

indexShortLink,

indexIsParseOk,

indexErrType,

indexRealGameName,

indexGameTheme,

]

mongoCollectionShortlink.create_indexes(indexModelList)

详见:(百度搜)

【已解决】用mongo的shell给MongoDB创建索引以提高查岁隐询速度

【已解决】PyMongo中如何一次性创建多个index索引

MongoDB 索引

Nothing like a little truth to sober you up.

唯有事实最能让人清醒。

索引支持在MongoDB中高效地执行查询。如果没有索引,MongoDB必须执行全集合扫描,即扫描集合中的每个文档,以选择与查询语句匹配的文档。这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。

如果查询存在适当的索引,MongoDB可以使用该索引限制必须检查的文档数。

索引是特殊的数据结构,它以易于遍历的形式存储集合数据集的一小部分。索引存储特定字段或一组字段的值,按字段值排序。索引项的排序支持有效的相等匹配和基于范围的查询操作。此外,MongoDB还可以使用索引中的排序返回排序结果。

官网文档:

MongoDB索引使用B树数据结构(确切的说是B-Tree,MySQL是B+Tree)

MongoDB的索引可以分为:单字段索引、复合索引以及地理空间索引等。

单字段索引:MongoDB支持在文档的单个字段上创建用户定义的升序/降序索引,称为单字段索引(Single Field Index)。

对于单个字段索引和排序操作,索引键的排序顺序(即升序或降序)并不重要,因为MongoDB可以在任何方向上遍历索引。

复合索引:MongoDB还支持多个字段的用户定义索引,即颂举复合索引(Compound Index)。

复合悄渣索引中列出的字段顺序具有重要意义。例如,如果复合索引由 { userid: 1, score: -1 } 组成,则索引首先按userid正序排序,然后在每个userid的值内,再在按score倒序排序。

其他索引:

地理空间索引(Geospatial Index):为了支持对地理空间坐标数据的有效查询,MongoDB提供了两种特殊的索引:返回结果时使用平面几何的二维索引和返回结果时使用球面几何的二维球面索引。

文本索引(Text Indexes):MongoDB提供了一种文本索引类型,支持在集合中搜索字符串内容。这些文本索引不存储特定于语言的停止词(例如“the”、“a”、“or”)启樱悄,而将集合中的词作为词干,只存储根词。

哈希索引(Hashed Indexes):为了支持基于散列的分片,MongoDB提供了散列索引类型,它对字段值的散列进行索引。这些索引在其范围内的值分布更加随机,但只支持相等匹配,不支持基于范围的查询。

查看索引

返回一个集合中的所有索引的数组

语法格式 : db.collection.getIndexes()

提示 :该语法命令运行要求是MongoDB 3.0+

示例

结果中显示的是默认 _id 索引。

默认_id索引 :MongoDB在创建集合的过程中,在 _id 字段上创建一个唯一的索引,默认名字为 id ,该索引可防止客户端插入两个具有相同值的文档,您不能在_id字段上删除此索引。

注意 :该索引是唯一索引,因此值不能重复,即 _id 值不能重复的。在分片集群中,通常使用 _id 作为片键。

创建索引

在集合上创建索引。

语法格式 : db.collection.createIndex(keys, options)

参数说明 :

options(更多选项)列表:

注意 :在 3.0.0 版本前创建索引方法为 db.collection.ensureIndex() ,之后的版本使用了 db.collection.createIndex() 方法, ensureIndex() 还能用,但只是 createIndex() 的别名。

实例

移除索引

可以移除指定的索引,或移除所有索引

语法格式 : db.collection.dropIndex(index) 或移除所有索引 db.collection.dropIndexes()

参数说明 :

实例

提示 : _id 的字段的索引是无法删除的,只能删除非 _id 字段的索引。

执行计划

分析查询性能(Analyze Query Performance)通常使用执行计划(解释计划、Explain Plan)来查看查询的情况,如查询耗费的时间、是否基于索引查询等。

那么,通常,我们想知道,建立的索引是否有效,效果如何,都需要通过执行计划查看。

语法格式 : db.collection.find(query,options).explain(options)

实例

涵盖查询Covered Queries

当查询条件和查询的投影仅包含索引字段时,MongoDB直接从索引返回结果,而不扫描任何文档或将文档带入内存。 这些覆盖的查询可以非常有效。

我的理解是类似于mysql的索引覆盖,无须回表查询。

实例

有故事的人,通常不喜欢讲故事。不想在嘴上卖力,是想在心中开发能量。沉默,是一种负重的坚强,是一种韬光养晦的低调。少说多做,才是最有力的践行。

请MongoDB的索引六种类型。

请MongoDB的索引六种类型。

正确答案:单字缺缓段索引:在文档的单个字段上创建用户定义的升序/降序索引。复合索引:包含多个字段的索引,一个复合索引最伏丛模多可以包含31个字段。多键索引:MongoDB会为数组中的每个元素创建索引。地理空间索引:对地理空间坐标数据的有效查询,包含平面几何的二维索引郑告和球面几何的二维球面索引。文本索引:在集合中搜索字符串内容,即进行文本检索查询。哈希索引:哈希索引是使用哈希函数来计算索引字段的哈希值。

MongoDB索引

对普通字段创建索引

对内嵌的文档字段创建索引

复合索引的字段顺序、字段的升降序对查询性能有影响,

也叫多值索引,

数组索引必然会使索引的条目和体积发生膨胀。为了避免时空,有必要在文档设计上做出一些限制毁弯运。

MongoDB不支持一个复合索引中同时出现多个数组字段。

专门用于实现位置检索的一种特殊索引。

例如:

location字段是一个内嵌型文档,用于表明商家的地理位置,其中type表示这是地图上的一个点,coordinates则是经纬度。

接下来创建一个2dsphere索引,如纤梁下:

最后,执行查询,检索附件5千米内的商家,如下:

例如闹宽

对于制定字段已经存在重复记录的集合,尝试创建唯一性索引会报错。

对于老化数据的处理,MongoDB提供了便捷的做法,TTL索引,通过声明一个日期类型的字段,然后在日期字段上加上TTL索引:

创建TTL索引后,该数据会在3600秒后过期,MongoDB会周期性运行后台线程中对该集合进行检查及数据清理工作。

云上MongoDB常见索引问题及最优索引规则大全

本文干货较多,建议收藏学习巧如。先将文章结构速览奉上:

一、背景

二、MongoDB执行计划

2.1 queryPlanner信息

2.2 executionStats信息

2.3 allPlansExecution信息

三、云上用户建索引常见问题及优化方法

3.1 等值类查询常见问题及优化方法

3.1.1 同一类查询创建多个索引问题

3.1.2 多字段等值查询组合索引顺序非最优

3.1.3 最左原则包含关系引起的重复索引

3.1.4 唯一字段和其他字段组合引起的无用重复索引

3.2 非等值类查询常见问题及优化方法

3.2.1 非等值组合查询索引不合理创建

3.2.2 等值+非等值组合查询索引字段顺序不合理

3.2.3 不同类型非等值查询优先级问题

3.3 OR类查询常见问题及优化方法

3.3.1 普通OR类查询优化方法

3.3.2 复杂OR类查询优化方法

3.4 SORT类排序查询常见问题及优化方法

3.4.1 单字段正反序排序查询引起的重复索引

3.4.2 多字段排序查询正反序问题引起索引无效

3.4.3 等值查询+多字段排序组合查询

3.4.4 等值查询+非等值查询+SORT排序查询

3.4.5 OR+SORT组合排序查询

3.5 无用索引优化方法

四、MongoDB不同类型查询最优索引总结

腾讯云MongoDB当前已服务于 游戏 、电商、社交、教育、新闻资讯、金融、物联网、软件服务、 汽车 出行、音视频等多个行业。

腾讯MongoDB团队在配合用户分析问题过程中,发现 云上用户存在如下索引共性问题 ,主要集中在如下方面:

本文 重点分析总结腾讯云上用户索引创建不合理相关的问题 ,通过本文可以学习到MongoDB的以下知识点:

本文总结的 《最优索引规则创建大全》 不仅仅适用于MongoDB,很多规则 同样适用于MySQL等关系型数据库 。

判断索引选择及不同索引执行家伙信息可以通过explain操作获取, MongoDB通过explain来获取尺信SQL执行过程信息 ,当前持续explain的请求命令包含以下几种:

aggregate, count, distinct, find, findAndModify, delete, mapReduce, and update。

详见explain官网链接:

explain可以携带以下几个参数信息,各参数信息功能如下:

2.1 queryPlanner信息

获取MongoDB查询优化器选择的最优索引和拒绝掉的非最优索引,并给出各个候选索引的执行阶段信息,queryPlanner输出信息如下:

queryPlanner输出主要包括如下信息:

parsedQuery信息

内核对查询条件进行序列化,生成一棵expression tree信息,便于候选索引查询匹配。

winningPlan信息

rejectedPlans信息

输出信息和winningPlan类似,记录这些拒绝掉索引的执行stage信息。

2.2 executionStats信息

explain的executionStats参数除了提孝困启供上面的queryPlanner信息外,还提供了最优索引的执行过程信息,如下:

上面是通过executionStats获取执行过程的详细信息,其中字段信息较多,平时分析索引问题最常用的几个字段如下:

executionStats输出字段较多,其他字段将在后续《MongoDB内核index索引模块实现原理》中进行进一步说明。

在实际分析索引问题是否最优的时候,主要查看以下三个统计项:

executionStats.totalKeysExamined

executionStats.totalDocsExamined

executionStats .nReturned

如果存在以下情况则说明索引存在问题,可能索引不是最优的:

1. executionStats.totalKeysExamine远大于executionStats .nReturned

2. executionStats. totalDocsExamined远大于executionStats .nReturned

2.3 allPlansExecution信息

allPlansExecution参数对应输出信息和executionStats输出信息类似,只是多了所有候选索引(包括reject拒绝的非最优索引)的执行过程,这里不再详述。

2.4 总结

从上面的几个explain执行计划参数输出信息可以看出,各个参数的功能各不相同,总结如下:

queryPlanner

输出索引的候选索引,包括最优索引及其执行stage过程(winningPlan)+其他非最优候选索引及其执行stage过程。

注意: queryPlanner没有真正在表中执行整个SQL,只做了查询优化器获取候选索引过程,因此可以很快返回。

executionStats

相比queryPlanner参数,executionStats会记录查询优化器根据所选最优索引执行SQL的整个过程信息,会真正执行整个SQL。

allPlansExecution

和executionStats类似,只是多了所有候选索引的执行过程。

在和用户一起优化腾讯云上MongoDB集群索引过程中,以及和头部用户的交流中发现很多用户对如何创建最优索引有较为严重的错误认识,并且很多是绝大部分用户的共性问题,因此在本文中将这些问题汇总如下:

3.1 等值类查询常见问题及优化方法

如下三个查询:

用户创建了如下3个索引:

{a:1, b:1, c:1}

{b:1, a:1, c:1}

{c:1, a:1, b:1}

实际上这3个查询属于同一类查询,只是查询字段顺序不一样,因此只需创建任一个索引即可满足要求。验证过程如下:

从上面的expalin输出可以看出,3个查询都走向了同一个索引。

例如test表有多条数据,每条数据有3个字段,分别为a、b、c。其中a字段有10种取值,b字段有100种取值,c字段有1000种取值,称为各个字段值的 “区分度” 。

用户查询条件为db.test.find({"a":"xxx", "b":"xxx", "c":"xxx"}),创建的索引为{a:1, b:1, c:1}。如果只是针对这个查询,该查询可以创建a,b,c三字段的任意组合,并且其SQL执行代价一样,通过hint强制走不通索引,验证过程如下:

从上面的执行计划可以看出,多字段等值查询各个字段的组合顺序对应执行计划代价一样。绝大部分用户在创建索引的时候,都是直接按照查询字段索引组合对应字段。

但是,单就这一个查询,这里有个不成文的建议,把区分度更高的字段放在组合索引左边,区分度低的字段放到右边。这样做有个好处,数据库组合索引遵从最左原则,就是当其他查询里面带有区分度最高的字段时,就可以快速排除掉更多不满足条件的数据。

例如用户有如下两个查询:

用户创建了如下两个索引:

{b:1, c:1}

{a:1,b:1,c:1}

这两个查询中,查询2中包含有查询1中的字段,因此可以用一个索引来满足这两个查询要求,按照最左原则,查询1字段放左边即可,该索引可以优化为:b,c字段索引+a字段索引,b,c字段顺序可以根据区分排序,加上c字段区分度比b高,则这两个查询可以合并为一个{c:1, b:1, a:1}。两个查询可以走同一个索引验证过程如下:

从上面输出可以看出,这两个查询都走了同一个索引。

例如用户有以下两个查询:

用户为这两个查询创建了两个索引,{a:1, b:1}和{a:1, c:1},但是a字段取值是唯一的,因此这两个查询中a以外的字段无用,一个{a:1}索引即可满足要求。

3.2 非 等值类查询常见索引错误创建方法及如何创建最优索引

假设用户有如下查询:

a,c两个字段都是非等值查询,很多用户直接添加了{a:1, c:1}索引,实际上多个字段的非等值查询,只有最左边的字段才能走索引,例如这里只会走a字段索引,验证过程如下:

从上面执行计划可以看出,索引数据扫描了10行(也就是a字段满足a:{$gte:1}条件的数据多少),但是实际上只返回了4条满足{a:{$gte:1}, c:{$lte:1}}条件的数据,可以看出c字段无法做索引。

同理,当查询中包含多个字段的范围查询的适合,除了最左边第一个字段可以走索引,其他字段都无法走索引。因此,上面例子中的查询候选索引为{a:1}或者{b:1}中任何一个就可以了,组合索引中字段太多会占用更多存储成本、同时占用更多IO资源引起写放大。

例如下面查询:

如上查询,d字段为非等值查询,e字段为等值查询,很多用户遇到该类查询直接创建了{d:1, e:1}索引,由于d字段为非等值查询,因此e字段无法走索引,验证过程如下:

从上面验证过程可以看出,等值类和非等值类组合查询对应组合索引,最优索引应该优先把等值查询放到左边,上面查询对应最优索引{e:1, d:1}

前面用到的非等值查询操作符只提到了比较类操作符,实际上非等值查询还有其他操作符。常用非等值查询包括:$gt、$gte、$lt、$lte、$in、$nin、$ne、$exists、$type等,这些非等值查询在绝大部分情况下存在如下优先级:

从上到下优先级更高,例如下面的查询:

如上,该查询等值部分查询最优索引{a:1, b:1}(假设a区分度比b高);非等值部分,因为$in操作符优先级最高,排他性更好,加上多个字段非等值查询只会有一个字段走索引,因此非等值部分最优索引为{g:1}。

最终该查询最优索引为:”等值部分最优索引”与”非等值部分最优索引”拼接,也就是{a:1,b:1, g:1}

3.3 OR类查询常见索引错误创建方法及如何创建最优索引

例如下面的OR查询:

该查询很多用户直接创建了{b:1, d:1, c:1, a:1},用户创建该索引后,发现用户还是全表扫描。

OR类查询需要给数组中每个查询添加索引,例如上面or数组中实际包含{ b: 0, d:0 }和 {"c":1, "a":{$gte:4}}查询,需要创建两个查询的最优索引,也就是{b:1, d:1}和{c:1, a:1},执行计划验证过程如下(该测试表总共10条数据):

从上面执行计划可以看出,如果该OR类查询走{b:1, d:1, c:1, a:1}索引,则实际上做了全表扫描。如果同时创建{b:1, d:1}、{c:1, a:1}索引,则直接走两个索引,其执行key和doc扫描行数远远小于全表扫描。

这里在提升一下OR查询难度,例如下面的查询:

上面的查询可以转换为如下两个查询:

如上图,查询1拆分后的两个查询2和查询3组成or关系,因此对应最优索引需要创建两个,分表是:{f:1, g:1, b:1, d:1} 和 {f:1, g:1, b:1, d:1}。对应执行计划如下:

同理,不管怎么增加难度,OR查询最终可转换为多个等值、非等值或者等值与非等值组合类查询,通过如上变换最终可以起到举一反三的作用。

说明:这个例子中可能在一些特殊数据分布场景,最优索引也可能是{f:1, g:1}或者{f:1, g:1, b:1, d:-1}或者{ f:1, g:1, c:1, a:1},这里我们只考虑大部分通用场景。

3.4 SORT类排序查询常见索引错误创建方法及如何创建最优索引

例如用户有以下两个查询:

这两个查询都不带条件,排序方式不一样,因此很多创建了两个索引{a:1}和{a:-1},实际上这两个索引中的任何一个都可以满足两种查询要求,验证过程如下:

假设有如下查询:

其中a字段为正序,b字段为反序排序,很多用户直接创建{a:1, b:1}索引,这时候b字段内容就存在内存排序情况。多字段排序索引,如果没有携带查询条件,则最优索引即为排序字段对应索引,这里切记保持每个字段得正反序和sort完全一致,否则可能存在部分字段内存排序的情况,执行计划验证过程如下:

例如如下查询:

该类查询很多人直接创建{a:1, b:1, c:1, d:1},结果造成内存排序。这种组合查询最优索引=“多字段等值查询最优索引_多字段排序类组合最优索引”,例如该查询:

{ "a" : 3, "b" : 1}等值查询假设a区分度比b高,则对应最优索引为:{a:1, b:1}

{ c:-1, d:1}排序类查询最优索引保持正反序一致,也就是:{ c:-1, d:1}

因此整个查询就是这两个查询对应最优索引拼接,也就是{a:1, b:1, c:-1, d:1},对应执行计划过程验证如下:

假设有下面的查询:

腾讯云很多用户看到该查询直接创建{a:1, b:1, c:1, d:-1, e:1}索引,发现存在内存排序。等值+非等值+sort排序组合查询,由于非等值查询右边的字段不能走索引,因此如果把d, e放到c的右边,则d,e字段索引无效。

等值+非等值+sort排序最优索引组合字段顺序为:等值_sort排序_非等值,因此上面查询最优索引为:{a:1, b:1, d:-1, e:1, c:1}。执行计划验证过程如下:

例如如下查询:

上面组合很多人直接创建{b:1, d:1, c:1, a:1, e:1},该索引创建后还是会扫表和内存排序,实际上OR+SORT组合查询可以转换为下面两个查询:

所以这个复杂查询就可以拆分为等值组合查询+sort排序查询,拆分为上面的两个查询,这样我们只需要同时创建查询2和查询3对应最优索引即可。该查询最终拆分后对应最优索引需要添加如下两个:

{b:1, d:1, e:-1}和{c:1, a:1, e:-1}

非最优索引和最优索引执行计划验证过程如下:

OR+SORT类查询,最终可以《参考前面的OR类查询常见索引错误创建方法》把OR查询转换为多个等值、非等值或者等值与非等值组合查询,然后与sort排序对应索引字段拼接。例如下面查询:

拆分后的两个查询组成or关系,如下:

如上,查询1 = or: [查询2, 查询3],因此只需要创建查询2和查询3两个最优索引即可满足查询1要求,查询2和查询3最优索引可以参考前面《or类查询常见索引错误创建方法》,该查询最终需要创建如下两个索引:

{f:1, g:1, b:1, d:1, e:-1}和{ f:1, g:1, c:1, a:1, e:-1}

说明:这个例子中可能在一些特殊数据分布场景,最优索引也可能是{f:1, g:1}或者{f:1, g:1, b:1, d:1, e:-1}或者{ f:1, g:1, c:1, a:1, e:-1},这里我们只考虑通用场景。

3.5 避免创建太多无用索引及无用索引分析方法

在腾讯云上,我们还发现另外一个问题,很多实例存在大量无用索引,无用索引会引起以下问题:

存储成本增加

没增加一个索引,MongoDB内核就会创建一个index索引文件,记录该表的索引数据,造成存储成本增加。

影响写性能

用户没写入一条数据,就会在对应索引生成一条索引KV,实现索引与数据的一一对应,索引KV数据写入Index索引文件过程加剧写入负载。

影响读性能

MongoDB内核查询优化器原理是通过候选索引快速定位到满足条件的数据,然后采样评分。如果满足条件的候选索引越多,整个评分过程就会越长,增加内核选择最优索引的流程。

下面以一个真实线上实例为例,说明如何找出无用索引:

MongoDB默认提供有索引统计命令来获取各个索引命中的次数,该命令如下:

该聚合输出中的几个核心指标信息如下表:

上表中的ops代表命中次数,如果命中次数为0或者很小,说明该索引很少被选为最优索引使用,因此可以认为是无用索引,可以考虑删除。

说明:

本文总结的《最优索引规则大全》中的规则适用于绝大部分查询场景,但是一些特殊数据分布场景可能会有一定偏差,请根据实际数据分布进行查询计划分析。

DBbrain for MongoDB

最后,本文中所介绍的优化原理即将集成到腾讯云DBbrain for MongoDB的智能索引推荐(规则+代价计算)功能中,届时可帮助用户一键优化索引,无需亲自反复推敲验证,欢迎体验。

腾讯云MongoDB当前服务于 游戏 、电商、社交、教育、新闻资讯、金融、物联网、软件服务等多个行业;MongoDB团队(简称CMongo)致力于对开源MongoDB内核进行深度研究及持续性优化(如百万库表、物理备份、免密、审计等),为用户提供高性能、低成本、高可用性的安全数据库存储服务。后续持续分享MongoDB在腾讯内部及外部的典型应用场景、踩坑案例、性能优化、内核模块化分析。

叮咚买菜自建MangoDB上腾讯云实践

关于mongodb创建索引和mongodb创建索引阻塞的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

标签列表