Mam istniejący stół:
CREATE TABLE dbo.ProofDetails
(
ProofDetailsID int NOT NULL
CONSTRAINT PK_ProofDetails
PRIMARY KEY CLUSTERED IDENTITY(1,1)
, ProofID int NULL
, IDShownToUser int NULL
, UserViewedDetails bit NOT NULL
CONSTRAINT DF_ProofDetails_UserViewedDetails
DEFAULT ((0))
);
Ta tabela ma 150 000 000 wierszy. System działa 24x7x365, więc nie ma regularnie występujących okien serwisowych.
Chcę dodać indeks do tabeli, a wraz z wersją SQL Server Enterprise, powinienem móc to zrobić bez blokowania dostępu do zapisu w tabeli. Polecenie, którego użyłem to:
CREATE INDEX IX_ProofDetails_ProofID_Etc
ON dbo.ProofDetails (ProofID, IDShownToUser)
INCLUDE (UserViewedDetails)
WITH (ONLINE=ON
, ALLOW_ROW_LOCKS=ON
, ALLOW_PAGE_LOCKS=ON
, FILLFACTOR=100
, MAXDOP=4
);
Sam wykonałem instrukcję w SSMS, naciskając F5. Trwało to ponad minutę, a następnie zaczęło blokować inne sesje. Następnie natychmiast anulowałem CREATE INDEX
polecenie, ponieważ nie mogę zablokować innych sesji.
W pierwszej minucie nic nie blokowało mojej CREATE INDEX
komendy, sys.dm_exec_requests
pokazało proces z typem oczekiwania CXPACKET
- oczywiście. Nie sądzę, żeby to było złe, ponieważ operacja została zrównoleglona.
Nie miałem dużo czasu na sprawdzenie wyników sys.dm_exec_requests
. Został zwrócony tylko jeden wiersz z zapytania WHERE session_id = xxx
. Zablokowane sesje próbowały wstawić wiersze do tabeli docelowej.
Nie wiem, jak długo trwały blokady, z wyjątkiem tego, że anulowałem wykonanie instrukcji około 2 minuty po jej uruchomieniu. W tym momencie pojawiały się bloki.
Czy źle zrozumiałem wdrożenie WITH (ONLINE=ON)
? Czy jest coś jeszcze, o czym muszę wiedzieć?
Serwer jest dość mocną maszyną, z 2 czterordzeniowymi procesorami Xeon E5-2643 3,3 GHz, 192 GB pamięci RAM i pamięcią SAN zdolną do ponad 5000 Iops. Procesor jest zwykle poniżej 20%, pamięć RAM jest wykorzystywana w 93%, głównie przez SQL Server. W tym pudełku nie działa nic więcej, tylko Windows Server 2012 i SQL Server 2012.
źródło