MongoDB インデックス
指数の分類
インデックス設計の原則
インデックス操作
インデックスを作成する
db.collection.createIndex(keys, options)
パラメータ_ |
種類_ |
説明_ |
2 |
ブール値 |
インデックス構築プロセスは他のデータベース操作をブロックします。また、バックグラウンドでインデックスを作成するように指定できます 。つまり、オプションの パラメーター。 「背景」のデフォルトは false です。 |
ユニークな |
ブール値 |
作成されたインデックスが一意であるかどうか。一意のインデックスを作成するには true を指定します。デフォルト値はfalseです。 |
名前_ |
弦 |
インデックスの名前。指定しない場合、MongoDB はインデックスの フィールド名と並べ替え順序を連結してインデックス名を生成します。 |
dr opDups |
ブール値 |
バージョン 3.0 以降は非推奨に。一意のインデックスを作成するときに重複レコードを削除するかどうか。 一意のインデックスを作成する場合はtrueを指定します。デフォルト値は false です。 |
まばらな |
ブール値 |
ドキュメント内に存在しないフィールド データのインデックス作成は有効ではありません。このパラメータには特別な注意が必要です。true に設定すると、対応するフィールドを含まないドキュメントはインデックス フィールドでクエリされなくなります。デフォルト値は false です。 |
秒後に期限切れになる |
私は整数 |
値を秒単位で 指定してTTL 設定を完了し、コレクションの有効期間を設定します。 |
v |
インデックスバージョン_ |
インデックスのバージョン番号。デフォルトのインデックスのバージョンは、インデックスの作成時に mongod が実行されていたバージョンによって異なります。 |
体重_ |
実行します |
インデックスの重み値。値は1 ~ 99,999 で、他のインデックス フィールドと比較したこのインデックス のスコアの重みを示します。 |
デフォルト言語 |
弦 |
テキストインデックス、このパラメータはストップワードのリスト とステミングとトークン化のルールを決定します 。デフォルトでは英語 |
言語_オーバーライド |
弦 |
テキストインデックスの場合、このパラメータはドキュメントに含まれるフィールド名、言語を指定します。 |
# 创建索引后台执行
db.values.createIndex({open: 1, close: 1}, {background: true})
# 创建唯一索引
db.values.createIndex({title:1},{unique:true})
インデックスを表示する
#查看索引信息
db.books.getIndexes()
#查看索引键
db.books.getIndexKeys()
インデックススペースの使用状況を表示する
db.collection.totalIndexSize([is_detail])
インデックスの削除
#删除集合指定索引
db.col.dropIndex("索引名称")
#删除集合所有索引 不能删除主键索引
db.col.dropIndexes()
インデックスタイプ
単一キーインデックス
db.books.createIndex({title:1})
複合インデックス
db.books.createIndex({type:1,favCount:1})
マルチキーインデックス
db.inventory.createIndex( { ratings: 1 } )
知らせ:
地理空間インデックス
db.restaurant.insert({
restaurantId: 0,
restaurantName: "兰州牛肉面",
location: {
type: "Point",
coordinates: [73.97, 40.77]
}
})
2dsphere インデックスを作成する
db.restaurant.createIndex({location : "2dsphere"})
全文索引 (テキスト索引)
MongoDBは全文検索機能をサポートしており、テキストインデックスを構築することで簡単な単語分割検索を実現できます。
db.reviews.createIndex( { comments: "text" } )
db.stores.insert([{
_id: 1,
name: "Java Hut",
description: "Coffee and cakes"
},
{
_id: 2,
name: "Burger Buns",
description: "Gourmet hamburgers"
},
{
_id: 3,
name: "Coffee Shop",
description: "Just coffee"
},
{
_id: 4,
name: "Clothes Clothes Clothes",
description: "Discount clothing"
},
{
_id: 5,
name: "Java Shopping",
description: "Indonesian goods"
}])
db.stores.createIndex({name: "text", description: "text"})
db.stores.find({$text: {$search: "java coffee shop"}})
ハッシュインデックス (ハッシュインデックス)
db.users.createIndex({username : 'hashed'})
ワイルドカードインデックス
db.products.insert([{
"product_name": "Spy Coat",
"product_attributes": {
"material": ["Tweed", "Wool", "Leather"],
"size": {
"length": 72,
"units": "inches"
}
}
},
{
"product_name": "Spy Pen",
"product_attributes": {
"colors": ["Blue", "Black"],
"secret_feature": {
"name": "laser",
"power": "1000",
"units": "watts",
}
}
},
{
"product_name": "Spy Book"
}])
db.products.createIndex( { "product_attributes.$**" : 1 } )
ワイルドカード インデックスは、単一フィールド クエリの product_attributes またはその埋め込みフィールドをサポートできます。
db.products.find( { "product_attributes.size.length" : { $gt : 60 } } )
db.products.find( { "product_attributes.material" : "Leather" } )
db.products.find( { "product_attributes.secret_feature.name" : "laser" })
考慮事項: ワイルドカード インデックスはインデックス タイプまたはプロパティと互換性がありません。
#通配符索引不能支持以下查询
db.products.find({
"product_attributes": {
$exists: false
}
})
db.products.aggregate([{
$match: {
"product_attributes": {
$exists: false
}
}
}])
#通配符索引不能支持以下查询:
db.products.find({ "product_attributes.colors" : [ "Blue", "Black" ] } )
db.products.aggregate([{
$match : { "product_attributes.colors" : [ "Blue", "Black" ] }
}])
インデックス属性
一意のインデックス
部分インデックス
db.restaurants.createIndex(
{ cuisine: 1, name: 1 },
{ partialFilterExpression: { rating: { $gt: 5 } } }
)
# 符合条件,使用索引
db.restaurants.find( { cuisine: "Italian", rating: { $gte: 8 } } )
# 不符合条件,不能使用索引
db.restaurants.find( { cuisine: "Italian" } )
スパースインデックス
#不索引不包含xmpp_id字段的文档
db.addresses.createIndex( { "xmpp_id": 1 }, { sparse: true } )
TTLインデックス
db.log_events.insertOne( {
"createdAt": new Date(),
"logEvent": 2,
"logMessage": "Success!"
} )
db.log_events.createIndex( { "createdAt": 1 }, { expireAfterSeconds: 20 })
最終的にはクリーンアップされ、データはクエリされませんでした
インデックスの使用に関する推奨事項
1. 各クエリに適切なインデックスを構築する
2. 適切な複合インデックスを作成し、クロスインデックスに依存しない
3. 複合インデックスフィールドの順序: 一致条件が最初、範囲条件が後 (等価性が最初、範囲が後)
4. 可能な限りカバードインデックスを使用する
5. インデックス作成はバックグラウンドで実行する必要があります
6. 長すぎる配列インデックスの設計を避ける
詳細な実行計画を説明する
db.collection.find().explain(<verbose>)
スキーマ名 |
説明 |
クエリプランナー_ |
実行プランの詳細 (クエリ プラン、コレクション情報、クエリ条件、最適な実行プラン、クエリ モード、MongoDB サービス情報など)。 |
実行駅 |
最適な実行計画および拒否された計画の実行状況などの情報 |
すべての計画の実行 |
最適な実行計画を選択して実行し、最適な実行計画と他の実行計画の実行を |
# 未创建title的索引
db.books.find({title:"book‐1"}).explain("queryPlanner")
フィールド名 |
説明 |
計画ナーバージョン |
実行計画のバージョン |
名前空間 |
クエリのコレクション |
ndexFilterSet内 |
インデックスを使用するかどうか |
解析された質問クエリ |
クエリ条件 |
勝利計画 |
最良の実行計画 |
たげ_ |
クエリ方法 |
フィルター |
フィルター条件 |
方向_ |
クエリの順序 |
拒否された計画 |
拒否された実行計画 |
サーバー情報 |
mongodbサーバー情報 |
実行統計
#创建索引
db.books.createIndex({title:1})
db.books.find({title:"book‐1"}).explain("executionStats")
{
"createdCollectionAutomatically" : true,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.books.find({title:"book‐1"}).explain("executionStats")
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "restaurant.books",
"indexFilterSet" : false,
"parsedQuery" : {
"title" : {
"$eq" : "book‐1"
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"title" : 1
},
"indexName" : "title_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"title" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"title" : [
"[\"book‐1\", \"book‐1\"]"
]
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 0,
"executionTimeMillis" : 0,
"totalKeysExamined" : 0,
"totalDocsExamined" : 0,
"executionStages" : {
"stage" : "FETCH",
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 1,
"advanced" : 0,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"docsExamined" : 0,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 1,
"advanced" : 0,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"keyPattern" : {
"title" : 1
},
"indexName" : "title_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"title" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"title" : [
"[\"book‐1\", \"book‐1\"]"
]
},
"keysExamined" : 0,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0
}
}
},
"serverInfo" : {
"host" : "192.168.30.130",
"port" : 27017,
"version" : "4.4.9",
"gitVersion" : "b4048e19814bfebac717cf5a880076aa69aba481"
},
"ok" : 1
}
フィールド名 |
説明 |
勝利計画。入力ステージ |
子ステージを記述し 、その親ステージにドキュメント キーと インデックスキーを提供するために使用されます。 |
優勝プラン。inputStage 。ステージ |
サブクエリメソッド |
優勝プラン。inputStage.keyPattern |
スキャンされたインデックスの内容 |
優勝プラン。inputStage.indexName |
インデックス名 |
優勝プラン。inputStage.isMultiKey |
マルチキーかどうか。インデックスが配列に構築されている 場合はtrue になります |
実行統計。実行成功 |
実行が成功したかどうか |
実行統計。n返品されました |
返された番号 |
実行統計。実行時間ミリス |
このステートメントの実行時間 |
executionStats.executionStages.executionTim eMillisEstimate |
检索文档获取数据的时间 |
executionStats.executionStages.inputStage.ex ecutionTimeMillisEstimate |
扫描获取数据的时间 |
executionStats.totalKeysExamined |
索引扫描次数 |
executionStats.totalDocsExamined |
文档扫描次数 |
executionStats.executionStages.isEOF |
是否到达 steam 结尾, 1 或者 true 代表已到达结 尾 |
executionStats.executionStages.works |
工作单元数 ,一个查询会分解成小的工作单元 |
executionStats.executionStages.advanced |
优先返回的结果数 |
executionStats.executionStages.docsExamine |
文档检查数 |
状态 |
描述 |
COLLSCAN |
全表扫描 |
IXSCAN |
索引扫描 |
FETCH |
根据索引检索指定文档 |
SHARD_MERGE |
将各个分片返回数据进行合并 |
SORT |
在内存中进行了排序 |
LIMIT |
使用limit限制返回数 |
SKIP |
使用skip进行跳过 |
IDHACK |
对_id进行查询 |
SHARDING_FILTER |
通过mongos对分片数据进行查询 |
COUNTSCAN |
count不使用Index进行count时的stage返回 |
COUNT_SCAN |
count使用了Index进行count时的stage返回 |
SUBPLA |
未使用到索引的$or查询的stage返回 |
TEXT |
使用全文索引进行查询时候的stage返回 |
PROJECTION |
限定返回字段时候stage的返回 |