Sposób, w jaki zrobiłem to w kilku projektach, polega na użyciu dwóch kopii tabeli w różnych schematach. Czyli coś takiego:
CREATE SCHEMA fake WITH AUTHORIZATION dbo;
CREATE SCHEMA standby WITH AUTHORIZATION dbo;
GO
CREATE TABLE dbo.mySummary(<...columns...>);
CREATE TABLE fake.mySummary(<...columns...>);
GO
Teraz utwórz procedurę składowaną, która obcina i ponownie wypełnia fałszywą tabelę, a następnie w transakcji przenieś obiekty między schematami.
CREATE PROCEDURE dbo.SwapInSummary
AS
BEGIN
SET NOCOUNT ON;
TRUNCATE TABLE fake.mySummary;
INSERT fake.mySummary(<...columns...>)
SELECT <expensive query>;
BEGIN TRANSACTION;
ALTER SCHEMA standby TRANSFER dbo.mySummary;
ALTER SCHEMA dbo TRANSFER fake.mySummary;
ALTER SCHEMA fake TRANSFER standby.mySummary;
COMMIT TRANSACTION;
END
GO
Jest to prawdopodobnie najkrótszy czas, jaki możesz zmusić użytkowników do oczekiwania na odświeżenie nowych danych i bez zakłócania ich w trakcie odczytu. (Jest wiele problemów związanych z NOLOCK, które czynią go mniej pożądaną alternatywą, choć trzeba przyznać, że jest łatwy do zakodowania.) Dla zwięzłości/klarowności pominąłem obsługę błędów itp., i powinienem również zaznaczyć, że jeśli używasz skrypty do synchronizacji baz danych, upewnij się, że nazwy ograniczeń, indeksów itp. są takie same w obu tabelach, w przeciwnym razie przez połowę czasu nie będziesz zsynchronizowany. Pod koniec procedury możesz OBCIĄGNĄĆ nową tabelę fake.MySummary, ale jeśli masz miejsce, lubię tam zostawić dane, aby zawsze móc porównać z poprzednią wersją.
Przed SQL Server 2005 używałem sp_rename wewnątrz transakcji, aby osiągnąć dokładnie to samo, jednak ponieważ robię to w pracy, cieszyłem się z przejścia na schematy, ponieważ kiedy to zrobiłem, ostrzeżenie o braku możliwości wyłączenia sp_rename przestało się wypełniać wpisać moje dzienniki historii agenta SQL Server.