《MongoDB入门教程》第29篇 复合索引

本文将会介绍 MongoDB 复合索引的概念,以及如何创建复合索引。

复合索引

复合索引(compound index)是指基于多个字段的索引,通常可以用于优化匹配多个字段的查询。

复合索引同样可以使用 createIndex() 方法创建,语法如下:

db.collection.createIndex({
    
    
    field1: type,
    field2: type,
    field3: type,
    ...
});

其中,field1、field2、field3 都是字段;type 代表了类型,1 表示索引中的数据按照升序排列,-1 表示按照降序排列。

ℹ️MongoDB 复合索引最多包含 32 个字段。

复合索引中的字段顺序至关重要。如果一个复合索引包含字段 field1、field2,索引首先按照 field1 进行排序,如果 field1 相同,再按照 field2 排序。

复合索引遵循最左匹配原则。例如,一个复合索引包含字段 field1、field2,可以支持以下查询优化:

  • 基于字段 field1 的匹配
  • 基于字段 field1 以及 field2 的匹配

但是,它不支持基于字段 field2 的查询优化。

优化示例

首先,我们为集合 movies 创建一个基于 Title 以及 Release Date 的复合索引:

db.movies.createIndex({
    
     Title: 1, 'Release Date': 1 })

'Title_1_Release Date_1'

然后查找名称包含 batman,并且在 2005 年 1 月 15 日发行的电影:

db.movies.find({
    
    Title: /batman/i, "Release Date": 'Jun 15 2005'}).explain('executionStats');

...
      inputStage: {
    
    
        stage: 'IXSCAN',
        filter: {
    
    
          Title: BSONRegExp("batman", "i")
        },
        nReturned: 1,
        executionTimeMillisEstimate: 5,
        works: 3180,
        advanced: 1,
        needTime: 3178,
        needYield: 0,
        saveState: 3,
        restoreState: 3,
        isEOF: 1,
        keyPattern: {
    
    
          Title: 1,
          'Release Date': 1
        },
        indexName: 'Title_1_Release Date_1',
...

查询使用了索引 Title_1_Release Date_1,而不是扫描整个集合。

然后查找名称包含 batman 的电影:

db.movies.find({
    
    Title: /batman/i}).explain('executionStats');

...
      inputStage: {
    
    
        stage: 'IXSCAN',
        filter: {
    
    
          Title: BSONRegExp("batman", "i")
        },
        nReturned: 6,
        executionTimeMillisEstimate: 0,
        works: 3192,
        advanced: 6,
        needTime: 3185,
        needYield: 0,
        saveState: 3,
        restoreState: 3,
        isEOF: 1,
        keyPattern: {
    
    
          Title: 1,
          'Release Date': 1
        },
        indexName: 'Title_1_Release Date_1',
...

以上查询只匹配了 Title,优化器仍然能够使用复合索引进行优化。

然后查找在 2005 年 1 月 15 日发行的电影:

db.movies.find({
    
    "Release Date": 'Jun 15 2005'}).explain('executionStats');

...
    executionStages: {
    
    
      stage: 'COLLSCAN',
      filter: {
    
    
        'Release Date': {
    
    
          '$eq': 'Jun 15 2005'
        }
      },
      nReturned: 1,
...

这种情况下,查询优化器无法使用复合索引,而是通过扫描整个集合(COLLSCAN)查找数据。

猜你喜欢

转载自blog.csdn.net/horses/article/details/129201508