在未索引的資料行上查詢
「最佳化」提供建議,協助您識別並解決因資料庫索引遺失而造成的效能問題。
以下針對 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
時。
何時不使用索引
- 小型資料表: 對於列數很少的資料表,維護索引的額外負擔可能不值得效能提升。
- 寫入密集型資料表: 索引可能會減慢寫入操作 (
create
、update
、delete
) 的速度,因為索引也需要更新。避免在寫入操作頻繁的模型上過度建立索引。 - 不常存取的資料表: 如果很少存取資料表,索引的好處可能不足以證明額外負擔的合理性。
- 具有大型資料的資料行: 索引具有大型資料的資料行可能會導致更高的儲存需求,並且可能無法提供顯著的效能改進。
- 很少篩選的資料行: 如果經常存取資料表,但很少依特定資料行篩選,則在該資料行上建立索引可能沒有益處。
警告
即使您為資料行建立索引,資料庫也可能不總是使用它。許多資料庫管理系統,例如 PostgreSQL 和 MySQL,都有一個查詢最佳化器,它會評估多個執行計畫,並選擇它估計最有效率的計畫。在某些情況下,這可能涉及忽略現有的索引,而選擇它認為對於特定查詢效能更好的不同執行計畫。