共用方式為


Azure DocumentDB 中的索引最佳做法

可查詢欄位應該總是建立索引

根據述詞和彙總的讀取作業會參考對應篩選的索引。 若缺乏索引,資料庫引擎會執行文件掃描以取得匹配的文件。 掃描的成本總是很高,且隨著資料集合中的資料量增加而愈加昂貴。 為了達到最佳查詢效能,所有可查詢欄位都應建立索引。

避免不必要的索引,並預設索引所有欄位

索引應該只為可查詢欄位建立。 萬用字索引應僅在查詢模式不可預測且文件結構中任何欄位皆可成為查詢篩選器的一部分時使用。

小提示

Azure DocumentDB 預設只會索引_id欄位。 其他欄位預設不會被索引。 要索引的欄位應事先規劃,以最大化查詢效能,同時盡量減少索引過多欄位對寫入的影響。

當首次插入新文件或更新或刪除現有文件時,索引中指定的欄位也會同步更新。 若索引政策包含大量欄位(或文件中所有欄位),伺服器在更新相應索引時會消耗更多資源。 大規模執行時,應該只針對可查詢欄位編製索引,而查詢述詞中未使用的所有剩餘欄位都應該保持從索引中排除。

有效資料擷取的索引策略

對於大規模工作負載遷移到 Azure DocumentDB,建議在資料負載後建立索引以提升執行效率。 這大幅降低寫入開銷、最小化資源消耗,並加速資料擷取效能。 在大量擷取期間維持索引可能會拖慢插入速度,因為每次寫入操作都必須更新所有適用的索引。

對於在歷史資料上建立的多個索引,請對每個欄位發出非阻塞的 createIndex 指令

並非總是能事先規劃所有查詢模式,尤其隨著應用程式需求演變。 應用程式需求變化不可避免地需要在包含大量歷史資料的叢集索引中新增欄位。

在這種情況下,每個 createIndex 指令都應該非同步地發出,不要等待伺服器回應。

備註

預設情況下,Azure DocumentDB 只有在索引完全建立於歷史資料後才會回應 createIndex 操作。 根據叢集的大小及資料量,這可能需要時間,且看起來伺服器沒有回應 createIndex 指令。

如果 createIndex 指令是透過 Mongo Shell 發出,請使用 Ctrl + C 中斷指令,停止等待回應並發出下一組操作。

備註

在 createIndex 指令發出後,使用 Ctrl + C 中斷該指令,並不會終止伺服器上的索引建置操作。 它只是停止 Shell 等待伺服器的回應,同時伺服器非同步繼續在現有文件上建立索引。

為包含多個欄位謂詞的查詢建立複合索引

複合索引應用於以下情境:

  • 多欄位的篩選查詢
  • 查詢時會對多個欄位進行篩選,且一個或多個欄位依升序或降序排序

請參考「cosmicworks」資料庫與「員工」收藏中的以下文件

{
    "firstName": "Steve",
    "lastName": "Smith",
    "companyName": "Microsoft",
    "division": "Azure",
    "subDivision": "Data & AI",
    "timeInOrgInYears": 7
}

請考慮以下查詢,以查找所有在該組織工作超過五年的姓氏為「Smith」的員工:

db.employee.find({"lastName": "Smith", "timeInOrgInYears": {"$gt": 5}})

在「姓氏」和「timeInOrgInYears」上使用複合索引來優化此查詢:

use cosmicworks;
db.employee.createIndex({"lastName" : 1, "timeInOrgInYears" : 1})

追蹤 createIndex 操作的狀態

當新增索引且需要索引歷史資料時,可使用 db.currentOp() 追蹤索引建置操作的進度。

您可以考慮此實例來追蹤「cosmicworks」資料庫的索引的進度。

use cosmicworks;
db.currentOp()

當 createIndex 操作進行中時,回應如下:

{
  "inprog": [
    {
      "shard": "defaultShard",
      "active": true,
      "type": "op",
      "opid": "30000451493:1719209762286363",
      "op_prefix": 30000451493,
      "currentOpTime": "2024-06-24T06:16:02.000Z",
      "secs_running": 0,
      "command": { "aggregate": "" },
      "op": "command",
      "waitingForLock": false
    },
    {
      "shard": "defaultShard",
      "active": true,
      "type": "op",
      "opid": "30000451876:1719209638351743",
      "op_prefix": 30000451876,
      "currentOpTime": "2024-06-24T06:13:58.000Z",
      "secs_running": 124,
      "command": { "createIndexes": "" },
      "op": "workerCommand",
      "waitingForLock": false,
      "progress": {},
      "msg": ""
    }
  ],
  "ok": 1
}

預設啟用大型索引鍵

即使文件中沒有大量字元的鍵,或文件中沒有多層巢狀結構,指定大型索引鍵也能確保這些情境都能被涵蓋。 現在,大型索引鍵是引擎的預設行為。

請考慮此範例,以啟用「cosmicworks」資料庫中「large_index_coll」集合的大型索引鍵。

use cosmicworks;
db.runCommand(
{
 "createIndexes": "large_index_coll",
 "indexes": [
    {
        "key": { "ikey": 1 },
        "name": "ikey_1",
        "enableLargeIndexKeys": true
    }
    ]
})

使用阻塞選項來優先建立索引而非新寫入操作

若索引應在資料載入前建立,應使用阻擋選項阻擋入入,直到索引建置完成。

設定 { "blocking": true } 在遷移工具中非常有用,因為在資料寫入開始前,會在空集合上建立索引。

請舉一個在「cosmicworks」資料庫中「employee」集合建立索引時的阻擋選項範例:

use cosmicworks;
db.runCommand({
  createIndexes: "employee",
  indexes: [{"key":{"name":1}, "name":"name_1"}],
  blocking: true
})

可以看看 文字索引,它能讓文字資料的搜尋和查詢更有效率。

後續步驟