Sql-Server

臨時設置 ALLOW_PAGE_LOCKS ON 有什麼影響

  • March 8, 2019

MSDN ALTER INDEX頁面顯示“當 ALLOW_PAGE_LOCKS 設置為 OFF 時,無法重新組織索引。”

我正在修改我們的索引重組/重建過程,以對已ALLOW_PAGE_LOCKS轉為OFF. 當我檢測到索引已關閉該選項時,我執行以下步驟:

BEGIN TRANSACTION
BEGIN TRY
   ALTER INDEX [MyIndex] ON [dbo].[MyTable] SET (ALLOW_PAGE_LOCKS = ON);
   ALTER INDEX [MyIndex] ON [dbo].[MyTable] REBUILD
       WITH (
           SORT_IN_TEMPDB = ON
           , MAXDOP = 1
           , PAD_INDEX = OFF
           , FILLFACTOR = 90
           , ALLOW_PAGE_LOCKS = OFF
           , ALLOW_ROW_LOCKS = ON
           , IGNORE_DUP_KEY = OFF
           , DATA_COMPRESSION = NONE
           );
   ALTER INDEX [MyIndex] ON [dbo].[MyTable] SET (ALLOW_PAGE_LOCKS = OFF);
   COMMIT TRANSACTION
END TRY
BEGIN CATCH
   ROLLBACK TRANSACTION
END CATCH

假設在此重建過程開始時數據庫實際上並未“使用中”,這種模式是否存在任何問題?設置PAGE LOCKS ON會導致任何副作用嗎?

注意 - 選項,例如FILLFACTOR = 90在開始重組/重建過程之前從索引的目前定義中獲取,並且根據索引中的頁數和碎片程度來決定是重組還是重建. 這個問題不是關於這些設置是“好”還是“壞”,它只是關於暫時轉向ALLOW_PAGE_LOCKS“ON”以允許對索引進行碎片整理的影響。

另外,我意識到該ALTER INDEX ... REBUILD語句有ALLOW_PAGE_LOCKS = OFF,而下一個語句也將其關閉…這是為了允許ALTER INDEX ... REORG存在任何選項的語句正常執行,同時在完成後也重置設置。ALLOW_PAGE_LOCKS

我已經將 alter index 語句包裝在事務中,僅針對具有的索引,ALLOW_PAGE_LOCKS OFF這樣如果在重建過程中出現任何問題,則不會修改索引。

另外,請注意,由於公司政策,我們沒有使用 Ola Hallengren 的解決方案。

編輯:

從@Shanky 的評論中,我已經確認ALTER INDEX ... REBUILD不需要ALLOW_PAGE_LOCKS ON僅在重組索引時才需要此選項。我已經修改了我的程式碼以僅在執行索引已經ALLOW_PAGE_LOCKS關閉的重組時執行上面顯示的事務包裝。

假設在此重建過程開始時數據庫實際上並未“使用中”

假設你假設什麼,我不知道它可能有什麼副作用,除了明顯允許索引 REORG 發生:-)。

當然,我沒有證據,但不確定當在此 REORG 操作之外的數據庫中沒有發生任何事情時,要尋找什麼證據表明不會發生任何不好的事情。

WITH NOCHECK如果使用跳過驗證的選項創建(並且在更改 using 之前不受信任),我也不知道這裡有任何類比外鍵不受信任,因此查詢優化器不會考慮WITH CHECK

關於索引屬性與索引頁面結構的概念:我想說這可以通過更改大索引來解決這個問題,只需打開和關閉這個選項。如果它立即發生,那麼它不會將更改寫入所有頁面。而且,這也可能是一個有爭議的問題,因為即使有變化,它也會通過 處理ALTER INDEX [MyIndex] ON [dbo].[MyTable] SET (ALLOW_PAGE_LOCKS = OFF);並在COMMIT. 儘管如此,我還是無法想像這只是一個簡單的索引屬性,因為它不能在每頁的基礎上進行更改。當然,這也可以通過DBCC PAGE在您進行此更改之前和之後查看索引的內容來查看。

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