🐥

ひとりMongoDB University / M201 MongoDB Performance(5)

2021/10/27に公開

この記録は、アドベントカレンダー形式ではじめた、MongoDB Universityの学習コースの記録の続きになります!

ただいまのコース

このコースでは、開発者 / オペレーション担当者双方向けの中級レベルの内容とのことです。
前回の記事は、ひとりMongoDB University / M201 MongoDB Performance(4) でした。

Lab 2.1: Using Indexes to Sort

Chapter 2 の演習問題です。
以下の設定でインデックスを作るのが前提。

# フィールド名と、ソートのオーダーの指定があります
# 複合インデックスです
{ "first_name": 1, "address.street": -1, "address.city": -1, "ssn": 1 }

Which of the following queries are able to use it for both filtering and sorting?

データの取得やソートの際に、このインデックスを利用するクエリはどれでしょう?

複合インデックスおさらい

  • クエリやソートは、インデックスで指定したキーの順番通りであることが条件
    • クエリの指定によってはインデックスをカバーしない場合がある
  • ソートの指定も注意

db.perple.createIndex({ "first_name": 1, "address.street": -1, "address.city": -1, "ssn": 1 })
'first_name_1_address.state_-1_address.city_-1_ssn_1'

exp = db.people.explain()

確認してみる。


# 予想 - 使われる
exp.find({ "first_name": "Jessica", "address.street": { $lt: "S"} }).sort({ "address.street": 1 })
{ queryPlanner:
   { plannerVersion: 1,
     namespace: 'sample_weatherdata.people',
     indexFilterSet: false,
     parsedQuery:
      { '$and':
         [ { first_name: { '$eq': 'Jessica' } },
           { 'address.state': { '$lt': 'S' } } ] },
     winningPlan: { stage: 'EOF' },
     rejectedPlans: [] },
  serverInfo:
   { host: 'cluster0-shard-00-01.t9q9n.mongodb.net',
     port: 27017,
     version: '4.4.10',
     gitVersion: '58971da1ef93435a9f62bf4708a81713def6e88c' },
  ok: 1,
  '$clusterTime':
   { clusterTime: Timestamp({ t: 1635343644, i: 15 }),
     signature:
      { hash: Binary(Buffer.from("0d79cb616f3956b3807813c042dc7453c22d1d8a", "hex"), 0),
        keyId: 6959643930757431000 } },
  operationTime: Timestamp({ t: 1635343644, i: 15 }) }

# 予想 - 使われない
db.people.find({ "first_name": "Jessica" }).sort({ "address.street": 1, "address.city": 1 }).explain()
# 結果:キーの並びと、ソートの条件が揃っているので使われる

# 予想: 使われない - # 結果:キーの並びがカバーされていないので、使われない
db.people.find({ "address.city": "West Cindy" }).sort({ "address.city": -1 })

# 予想: 使われない - # 結果:使われる
db.people.find({ "address.street": "South Dakota", "first_name": "Jessica" }).sort({ "address.city": -1 })


# 結果:使われない
db.people.find({ "first_name": { $gt: "J" } }).sort({ "address.city": -1 })

結果、ここが大事!

db.people.find({ "address.street": "South Dakota", "first_name": "Jessica" }).sort({ "address.city": -1 })

クエリでのフィールドの指定の順番は、重要じゃないみたい。
prefix に従っていれば、インデックスは使われるらしい。

  • address.street と first_name の両方がインデックス・プレフィックスに含まれているため、このクエリでは等号条件にインデックスを使用することができる

このあたりはもう少し確認すると良さそう....。

Lab 2.2: Optimizing Compound Indexes

「提示されたクエリの実行に当たって、一番効率が良いインデックスとなるのはどれ?」という問題。
こちらは割愛します。

ひとまず Chapter:2 はここまで。次の Chapter:3 では、Index Operation となります。

Discussion