Sql-Server

索引對更新列不在索引中的更新語句的影響

  • September 2, 2020

我經常看到人們說索引變慢了updatedelete而且insert。這被用作籠統的陳述,就好像它是絕對的。

在調整我的數據庫以提高性能時,我不斷遇到這種情況,這似乎在邏輯上與我的規則相矛盾,而且我找不到任何人以其他方式說或解釋。

在 SQL Server 中,我相信/假設大多數其他 DBMS,您的索引是根據您指定的特定列創建的。插入和刪除總是會影響一整行,所以它們不可能不影響索引,但更新似乎更獨特,它們只能具體影響某些列。

如果我有未包含在任何索引中的列並且我更新它們,它們是否會因為我在該表中的其他列上有索引而變慢?

例如,假設在我的User表中,我有一個或兩個索引,主鍵是身份/自動增量列,可能還有另一個外鍵列。

如果我更新一個沒有直接索引的列,比如他們的電話號碼或地址,這個更新是否會減慢,因為我在這表上的其他列上都有索引?我正在更新的列不在索引中,所以從邏輯上講,不應該更新索引,不是嗎?如果有的話,如果我使用 WHERE 子句中的索引,我會認為它們會加快速度。

您是正確的,更新非索引列不會導致索引更改。在一個簡單的情況下,也不會對桌子產生整體影響。

如果查詢可以使用索引來查找數據,它可能會加快查找速度,但確切的行為(取決於您的 SQL 品牌)可能與其他品牌的 SQL 不同。(我主要使用 Microsoft SQL Server。)

當然,使用大量數據更新列可能會導致某些行移動到不同的頁面,等等。

對於相對較快的現代系統,從性能的角度來看,對於絕大多數係統而言,向 OLTP 表添加單個索引可能幾乎無法檢測到。也就是說,您不應該創建不必要的索引,並且您可能不應該為表中的每一列創建單列索引。

您的假設是正確的,即對於許多查詢,有用的索引的存在將導致非常顯著的速度提高。

儘管您的問題似乎與性能有關,但添加索引還有其他幾個潛在問題,包括但不限於:

  1. 在將索引添加到表中時,創建索引所需的時間可能會導致阻塞。鎖的壽命很短,很可能不會造成大問題。
  2. 索引更改會導致任何引用基礎表的計劃的執行計劃無效。當重新編譯這些執行計劃時,某些查詢的性能可能會發生負面變化。
  3. 索引修改可能會導致查詢返回以前沒有返回的錯誤。以用於返回 varchar 欄位中包含的日期的過濾索引為例;如果過濾器消除了任何不是日期的行,並且隨後更改了該過濾器,則依賴該索引的查詢現在在嘗試轉換非日期數據時可能會失敗。
  4. 新的索引可能會導致執行順序發生變化,從而導致之前未發生的可能發生死鎖。

引用自:https://dba.stackexchange.com/questions/125300