MongoDB の豊富なインデックス タイプについて話しましょう

青灯夜游
リリース: 2022-02-17 10:59:16
転載
2394 人が閲覧しました

この記事では、MongoDB を理解し、MongoDB の豊富なインデックス タイプを紹介します。皆様のお役に立てれば幸いです。

MongoDB の豊富なインデックス タイプについて話しましょう

MongoDB のインデックスと MySql のインデックスの機能は、機能と最適化原則の点で基本的に似ています。 MySqlインデックス タイプは基本的に次のように区別できます。

  • 単一キー インデックス - ジョイント インデックス
  • 主キー インデックス (クラスター化インデックス) - 非主キー インデックス (非クラスター化インデックス)

MongoDB には、これらの基本的な分類に加えて、配列インデックス | スパース インデックス | 地理空間インデックス | TTL インデックスなどの特殊なインデックス タイプもあります。 etc.

以下のテストの便宜上、スクリプトを使用して次のデータを挿入します

for(var i = 0;i < 100000;i++){
    db.users.insertOne({
        username: "user"+i,
        age: Math.random() * 100,
        sex: i % 2,
        phone: 18468150001+i
    });
}
ログイン後にコピー

単一キー インデックス

単一キー インデックスの意味最も基本的なインデックスであるインデックス付きフィールドが 1 つだけであることを示します。Method.

コレクション内の

username フィールドを使用して、単一のキー インデックスを作成します。MongoDBこのインデックスには自動的に username_1

db.users.createIndex({username:1})
'username_1'
ログイン後にコピー

という名前が付けられます。インデックスを作成した後、

username フィールドを使用してクエリ プランを確認します。stage IXSCAN (インデックス スキャンが使用されることを意味します)

db.users.find({username:"user40001"}).explain()
{ 
   queryPlanner: 
   { 
     winningPlan: 
     { 
        ......
        stage: 'FETCH',
        inputStage: 
        { 
           stage: 'IXSCAN',
           keyPattern: { username: 1 },
           indexName: 'username_1',
           ......
        } 
     }
     rejectedPlans: [] ,
   },
   ......
   ok: 1 
}
ログイン後にコピー

インデックス最適化の原則の中で、非常に重要な原則は、インデックスはカーディナリティの高いフィールド上に構築されるべきであるということです。いわゆるカーディナリティは次のとおりです。フィールド内の非反復値の数、つまり

users を作成するとき。収集中に表示される年齢の値が 0-99 の場合、 age フィールドには 100 個の一意の値が含まれます。つまり、age フィールドのベースは 100 です。 sex フィールドには 2 つの値のみが含まれます 0 | 1、つまり、sex フィールドの基数は 2 であり、かなり低い基数です。この場合、インデックスの効率は高くなく、インデックスの失敗につながります。 # 実行プランをクエリするための

sex

フィールド インデックスを構築しましょう。クエリが関連インデックスなしでフル テーブル スキャンを実行したことがわかります。

db.users.createIndex({sex:1})
'sex_1'

db.users.find({sex:1}).explain()
{ 
  queryPlanner: 
  { 
     ......
     winningPlan: 
     { 
        stage: 'COLLSCAN',
        filter: { sex: { '$eq': 1 } },
        direction: 'forward' 
     },
     rejectedPlans: [] 
  },
  ......
  ok: 1 
}
ログイン後にコピー

ジョイント インデックス

結合インデックスは、インデックスに複数のフィールドが存在することを意味します。以下の

age## を使用します。# と

sex は、2 つのフィールド

db.users.createIndex({age:1,sex:1})
'age_1_sex_1'
ログイン後にコピー
## を持つインデックスを作成します# 次に、これら 2 つのフィールドを使用してクエリを実行し、実行計画を確認し、このインデックスを正常に実行します
db.users.find({age:23,sex:1}).explain()
{ 
  queryPlanner: 
  { 
     ......
     winningPlan: 
     { 
        stage: 'FETCH',
        inputStage: 
        { 
           stage: 'IXSCAN',
           keyPattern: { age: 1, sex: 1 },
           indexName: 'age_1_sex_1',
           .......
           indexBounds: { age: [ '[23, 23]' ], sex: [ '[1, 1]' ] } 
        } 
     },
     rejectedPlans: [], 
  },
  ......
  ok: 1 
 }
ログイン後にコピー

配列インデックス

配列インデックスは、配列フィールドのインデックス (複数値インデックスとも呼ばれます)。テストするために、users コレクション内のデータが以下のいくつかの配列フィールドに追加されます。

db.users.updateOne({username:"user1"},{$set:{hobby:["唱歌","篮球","rap"]}})
......
ログイン後にコピー

配列を作成するインデックスを作成し、その実行プランを表示します。isMultiKey: true は、使用されるインデックスが複数値のインデックスであることを意味します。

db.users.createIndex({hobby:1})
'hobby_1'

db.users.find({hobby:{$elemMatch:{$eq:"钓鱼"}}}).explain()
{ 
   queryPlanner: 
   { 
     ......
     winningPlan: 
     { 
        stage: 'FETCH',
        filter: { hobby: { '$elemMatch': { '$eq': '钓鱼' } } },
        inputStage: 
        { 
           stage: 'IXSCAN',
           keyPattern: { hobby: 1 },
           indexName: 'hobby_1',
           isMultiKey: true,
           multiKeyPaths: { hobby: [ 'hobby' ] },
           ......
           indexBounds: { hobby: [ '["钓鱼", "钓鱼"]' ] } } 
         },
     rejectedPlans: [] 
  },
  ......
  ok: 1 
}
ログイン後にコピー

配列インデックスは他のインデックスと比較されます。一般的に、インデックス エントリは、たとえば、各ドキュメントの hobby 配列の平均

size

が 10 である場合、このコレクションの hobby 配列インデックスは次のようになります。 結合配列インデックス

結合配列インデックスとは、配列フィールドを含む結合インデックスです。は 1 つのインデックスをサポートしません。複数の配列フィールドが含まれます。つまり、インデックス内に存在できる配列フィールドは最大 1 つです。これは、インデックス エントリの爆発的な増加を避けるためです。インデックス内に 2 つの配列フィールドがあると仮定すると、その数はインデックス エントリの数は、通常のインデックスの n* になります。m 倍

地理空間インデックス

元の users コレクションに地理情報を追加します。

for(var i = 0;i < 100000;i++){
    db.users.updateOne(
    {username:"user"+i},
    {
        $set:{
            location:{
                type: "Point",
                coordinates: [100+Math.random() * 4,40+Math.random() * 3]
            }
        }
    });
}
ログイン後にコピー

2 番目の次元空間インデックスの作成

db.users.createIndex({location:"2dsphere"})
'location_2dsphere'

//查询500米内的人
db.users.find({
  location:{
    $near:{
      $geometry:{type:"Point",coordinates:[102,41.5]},
      $maxDistance:500
    }
  }
})
ログイン後にコピー
地理空間インデックスの

type

には、

Ponit(point)

| を含むものが多数あります。 LineString(line) | Polygon (Polygon)etcTTL インデックス

TTL の完全なスペルは、time to です。 live は、主に期限切れデータの自動削除に使用されます。この種のインデックスを使用するには、ドキュメント内で時間型フィールドを宣言する必要があります。また、このフィールドの TTL インデックスを作成するときに、次のことも行う必要があります。

expireAfterSecondsを設定します

作成完了後の有効期限の単位は秒ですMongoDBコレクション内のデータは定期的にチェックされます。表示されるタイミング:

##現在時刻TT Lインデックス フィールド時間>exxpi reAfterSrconds現在時刻 - TTL インデックス フィールド時間>expireAfterSrconds
ソース:juejin.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!