Mysql

額外的索引會加劇鎖爭用嗎?

  • May 23, 2017

不考慮創建索引:在獲取鎖方面在表上創建索引是否是不利的?

我已經經歷過一些精心選擇的索引可以在數據庫中實現更高並行度的情況,正如MySQL 使用索引(間隙)鎖定所期望的那樣(並記錄在案)。

但是相反的情況是否也是可能的,即來自不同事務的兩個或多個查詢在沒有索引的情況下不會相互妨礙,但是給定一個額外的索引會導致額外的鎖等待?

我的問題不僅限於單個 RDS 實現,而是我對 MySQL 和 Postgres 最感興趣。

為Postgres說話。

在預設READ COMMITTED事務隔離中,索引不會引入死鎖的可能性,如果沒有它們就不會出現死鎖 - AFAIC。只有在創建新索引後,仍然可能會遇到死鎖。更改的查詢計劃可以使潛伏的設計問題作為副作用浮出水面,但不會作為索引的直接故障

創建或刪除索引是特殊的,引用手冊

在索引創建、銷毀或REINDEX.

並且存在SERIALIZABLE事務隔離的極端情況。請參閱手冊中“索引鎖定注意事項”一章的最後一段。(或閱讀全部內容以獲取詳細資訊。)

但是索引肯定會以各種方式加劇鎖爭用。顯然,額外的索引會導致寫入操作的額外成本(必須維護索引)。還有其他極端情況可能會以類似的效果損害性能。更長的事務意味著更多的鎖爭用,因為鎖只在事務結束時釋放。

對於大型插入或更新,刪除不相關的索引並在之後重新創建(在同一個事務中)以獲得更好的性能是值得的 - 但代價是表上的排他鎖。例子:

但是,通常情況下,如果您只創建實際需要的索引,情況恰恰相反:事務更短,鎖爭用更少。

有關的:

但是相反的情況是否也是可能的,即來自不同事務的兩個或多個查詢在沒有索引的情況下不會相互妨礙,但是給定一個額外的索引會導致額外的鎖等待?

我的問題不僅限於單個 RDS 實現,而是我對 MySQL 和 Postgres 最感興趣。

好吧,在一般情況下,答案是“是的,它可能可以”,因為您談論的是廣泛的數據庫。


特別是對於 PostgreSQL,添加索引肯定會損害寫入性能:

  • 每次插入元組時,每個索引都需要更新
  • 如果更改的任何列是一個或多個索引的一部分,則每個索引都需要在您UPDATE創建元組時更新。

如果您執行UPDATE不涉及任何索引列的操作,PostgreSQL 可以跳過索引更新。因此,添加索引可能會極大地損害寫入性能。

但是,它不會添加任何重要的鎖定,因為 PostgreSQL 不必專門鎖定索引,它允許對同一索引進行多次並發讀取和寫入。

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