lanlin / notes

个人笔记
https://github.com/lanlin/notes/issues
30 stars 0 forks source link

MongoDB 查询及索引设计原则 #79

Open lanlin opened 4 years ago

lanlin commented 4 years ago

一、索引设计原则

1.主键的设置: 业务无关、显示指定、递增属性

2.数据区分度: 原则上区分度高的字段优先做索引字段,如果是组合索引优先放前面

3.字段更新频率: 频繁更新的字段是否做索引字段需要综合考虑对业务的影响及查询的代价

4.前缀索引问题: 需要注意的是因前缀索引只包含部分值因此无法通过前缀索引优化排序

5.适当冗余设计: 对于存储较长字符串字段可额外增加字段存储原字段计算(如hash)后的值, 创建索引时只需要对额外字段创建索引即可

6.避免无效索引: 通常类似表已经含有主键ID就无需再创建额外唯一性的ID索引

7.查询覆盖率: 设计一个索引我们需要考虑尽量覆盖更多的查询场景

8.控制字段数: 如果你设计的索引例如含有7、8个字段通常需要考虑设计是否合理

lanlin commented 4 years ago

二、MongoDB 需要【尽量避免使用】的操作符列表

1.$where$exists: 这两个操作符, 完全不能使用索引。

2.$ne$not: 通常来说取反和不等于, 可以使用索引, 但是效率极低, 往往也会退化成扫描全表.

3.$nin: 不包含, 这个操作符也总是会全表扫描

4.管道中的索引只有在管道最开始时的 match sort 可以使用到索引. 一旦发生过 project 投射, group 分组, lookup 表关联,unwind 打散等操作后, 就完全无法使用索引.

lanlin commented 4 years ago

三、关于 explain 的解读

阅读说明:

在看查询结果的阶段树的时候是从【最里层】一层一层 【往外】 看的,不是直接顺着读下来的。

1.explain 结果将查询计划以阶段树的形式呈现。

2.每个阶段将其结果(文档或索引键)传递给父节点。

3.中间节点操纵由子节点产生的文档或索引键。

4.根节点是MongoDB从中派生结果集的最后阶段。

关键词说明:

关键词 说明
COLLSCAN 全表扫描
IXSCAN 索引扫描
FETCH 根据前面扫描到的位置抓取完整文档
SORT 进行内存排序, 最终返回结果
SORT_KEY_GENERATOR 获取每一个文档排序所用的键值
LIMIT 使用limit限制返回数
SKIP 使用skip进行跳过
IDHACK 针对_id进行查询
COUNTSCAN count不使用用Index进行count时的stage返回
COUNT_SCAN count使用了Index进行count时的stage返回
TEXT 用全文索引进行查询时候的stage返回
lanlin commented 4 years ago

MongoDB Index Cheat Sheet or MongoDB索引及排序备忘 #94