跳到主要內容

在未索引的資料行上查詢

「最佳化」提供建議,協助您識別並解決因資料庫索引遺失而造成的效能問題。

以下針對 User 模型的查詢,使用 where 屬性來篩選未建立索引的資料行

await prisma.user.findFirst({
where: {
name: "Marc"
}
})

await prisma.user.findFirst({
where: {
name: "Jon"
}
})

await prisma.user.count({
where: {
name: "Nikolas"
}
})

問題是什麼?

索引允許資料庫更快速地檢索資料,就像書中的索引幫助您找到資訊,而無需閱讀每一頁一樣。

當搭配 where 屬性使用 Prisma 時,如果相關資料行未定義索引,資料庫可能需要掃描資料表中的每一列(「完整資料表掃描」)才能找到符合的項目。這在幾個原因上可能是不理想的

使用者體驗

對於大型資料集,如果資料庫必須掃描整個資料表才能找到符合的列,使用者將會體驗到更長的等待時間。

資源利用率

  • CPU 使用率高: 掃描大型資料表會顯著增加 CPU 使用率,降低整體系統效能。
  • 記憶體消耗: 在完整資料表掃描期間,需要更多記憶體來處理和儲存資料。
  • 磁碟 I/O: 完整資料表掃描會增加磁碟輸入/輸出操作,可能減慢其他資料庫活動。
警告

雖然這些問題在開發環境中由於資料集較小可能不會顯現出來,但在生產環境中,資料集通常大得多,這些問題可能會變得非常嚴重。

更多關於資料庫索引的資訊

索引如何運作

索引建立一個資料結構,儲存索引資料行的值以及指向資料表中對應列的指標。當您使用索引資料行查詢資料庫時,資料庫可以使用此索引快速找到相關的列,而無需掃描整個資料表。

索引的權衡取捨

  • 空間與時間: 索引需要額外的儲存空間來儲存索引資料,但它可以顯著加快資料檢索速度。
  • 更新額外負擔: 每次在資料表中新增、更新或移除資料時,都需要額外的負擔來保持索引的更新,這可能會減慢寫入操作。

何時使用索引

  • 大型資料集: 索引對於具有大量列的資料表尤其有益。
  • 頻繁使用篩選或排序的查詢: 在經常用於篩選或排序的資料行上使用索引。
  • 查詢相關資料: 在外鍵資料行上使用索引,以加速檢索相關記錄,例如使用 include 時。

何時不使用索引

  • 小型資料表: 對於列數很少的資料表,維護索引的額外負擔可能不值得效能提升。
  • 寫入密集型資料表: 索引可能會減慢寫入操作 (createupdatedelete) 的速度,因為索引也需要更新。避免在寫入操作頻繁的模型上過度建立索引。
  • 不常存取的資料表: 如果很少存取資料表,索引的好處可能不足以證明額外負擔的合理性。
  • 具有大型資料的資料行: 索引具有大型資料的資料行可能會導致更高的儲存需求,並且可能無法提供顯著的效能改進。
  • 很少篩選的資料行: 如果經常存取資料表,但很少依特定資料行篩選,則在該資料行上建立索引可能沒有益處。
警告

即使您為資料行建立索引,資料庫也可能不總是使用它。許多資料庫管理系統,例如 PostgreSQL 和 MySQL,都有一個查詢最佳化器,它會評估多個執行計畫,並選擇它估計最有效率的計畫。在某些情況下,這可能涉及忽略現有的索引,而選擇它認為對於特定查詢效能更好的不同執行計畫。