2013-08-26 9 views
9

Biegniemy SQL Server 2012 SP1 x64 (11.0.3000.0)SQL Server: dowolna automatycznego przyrostu z klucza podstawowego

Mam poniższej tabeli z polem InvoiceId jako autoinkrementacja, klucz podstawowy:

CREATE TABLE Orders(
    InvoiceId   bigint   IDENTITY(1001,1) NOT FOR REPLICATION, 
    OrderId    varchar(8)  NOT NULL, 
    ... -- other fields removed for brevity 
    CONSTRAINT [PK_ORDERS] PRIMARY KEY CLUSTERED (InvoiceId) 
    ON [PRIMARY], 
) 

Nowe wiersze dodaje chociaż prosty sposób przechowywane jak następuje:

SET XACT_ABORT ON 
SET NOCOUNT ON 

BEGIN TRANSACTION 
    INSERT INTO Orders(
      OrderId, 
      ... -- other fields removed for brevity 
     ) 
    VALUES (
      @orderId, 
      ... 
     )    

    SELECT @newRowId = SCOPE_IDENTITY() 
COMMIT TRANSACTION 

powyższy sproc zwraca nowo utworzony rząd-ID (Orders.InvoiceId) do dzwoniącego.

Kod działał idealnie, z [InvoiceId] zaczynając od 1001 i zwiększając o 1 dla każdego kolejnego wkładu.

Nasi użytkownicy wstawili około 130 wierszy. [InvoiceId] był o 1130, a następnie przy następnym wstawieniu jego wartość przeskoczyła do !

Oto zrzut danych:

data

Jestem zaskoczony, co się stało tutaj. Dlaczego licznik autodostatków nagle pomija prawie 10 000 punktów?

Używamy wartości [InvoiceId] do generowania kodów kreskowych, więc wolimy, aby wartość pozostała w określonym zakresie, najlepiej w ciągłej serii.

Przeanalizowałem dokumentację T-SQL, ale nie znalazłem nic związanego z moim problemem. Czy jest to normalne zachowanie (dowolna populacja) pola tożsamości?

UPDATE Dzięki Martingowi & Aron, znalazłem obejście. Oto official response od Microsoft:

W SQL Server 2012 realizacja mienia tożsamość został zmieniony w celu dostosowania inwestycji do innych funkcji. W poprzednich wersjach SQL Server śledzenie generowania tożsamości opierało się na rekordach dziennika transakcji dla każdej wygenerowanej wartości tożsamości. W SQL Server 2012 generujemy wartości tożsamości w partiach i rejestrujemy tylko maksymalną wartość partii. Zmniejsza to ilość i częstotliwość informacji zapisywanych w dzienniku transakcji, poprawiając skalowalność wstawiania .

Jeśli wymagają tego samego semantykę generacji tożsamość jako poprzednia wersje SQL Server są dwie opcje:

• Korzystanie śladowej flaga 272 o spowoduje zapis dziennika mają być generowane dla każdego generowanego tożsamości wartość. Wydajność generowania tożsamości może zostać zakłócona przez włączenie tej flagi śledzenia.

• wykorzystać sekwencję generatora z ustawienie pamięcią podręczną (http://msdn.microsoft.com/en-us/library/ff878091.aspx) o tej spowoduje zapis dziennika jest generowany dla każdego wygenerowanego wartości sekwencji . Należy pamiętać, że wydajność generowania wartości sekwencji może mieć wartość , która ma wpływ na użycie opcji NO CACHE.

Przykład:

CREATE SEQUENCE s1 AS INT START WITH 1 NO CACHE; 
CREATE TABLE t1 (Id INT PRIMARY KEY DEFAULT NEXT VALUE FOR s1, col INT NOT NULL); 
+5

'IDENTITY' nigdy nie gwarantowane przyległe ale nie jest to znany problem w 2012 roku, gdzie może nagle wyskoczyć pozostawiając duże luki po ponownym uruchomieniu usługi. –

+0

Dzięki @MartinSmith! To wydaje się być problemem w moim przypadku. Pamiętam restartowanie maszyny db przed skokiem tożsamości! Jak mogę tego uniknąć? – masroore

+1

Nie można tego uniknąć, ponieważ nie gwarantowano zgodności, ale istnieje flaga śledzenia, którą można ustawić, aby uzyskać wolniejsze (zarejestrowane) zachowanie w wersji 2008 lub można użyć sekwencji o mniejszym rozmiarze pamięci podręcznej. Zobacz [dyskusja tutaj] (https://connect.microsoft.com/SQLServer/feedback/details/739013/failover-lub-restart-results-in-reseed-of-identity) –

Odpowiedz

2

AKTUALIZACJA Dzięki Martingowi & Aron, znalazłem obejście. Oto oficjalna odpowiedź firmy Microsoft:

W SQL Server 2012 implementacja właściwości tożsamości została zmieniona w celu uwzględnienia inwestycji w inne funkcje. W poprzednich wersjach SQL Server śledzenie generowania tożsamości opierało się na rekordach dziennika transakcji dla każdej wygenerowanej wartości tożsamości. W SQL Server 2012 generujemy wartości tożsamości w partiach i rejestrujemy tylko maksymalną wartość partii. Zmniejsza to ilość i częstotliwość informacji zapisywanych w dzienniku transakcji, poprawiając skalowalność płytki.

Jeśli wymagają tego samego semantykę generacji tożsamość poprzednich wersjach SQL Server są dwie opcje:

• Używaj flag ślad 272 O spowoduje zapis dziennika mają być generowane dla każdej wytworzonej wartości tożsamości. Na wydajność generowania tożsamości może wpłynąć włączenie tej flagi śledzenia.

• Użyj generatora sekwencji z ustawieniem NO CACHE (http://msdn.microsoft.com/en-us/library/ff878091.aspx) o Spowoduje to wygenerowanie rekordu dziennika dla każdej wygenerowanej wartości sekwencji. Zauważ, że na wydajność generowania wartości sekwencji może wpływać użycie NO CACHE.

Przykład:

CREATE SEQUENCE s1 AS INT START WITH 1 NO CACHE; 
CREATE TABLE t1 (Id INT PRIMARY KEY DEFAULT NEXT VALUE FOR s1, col INT NOT NULL); 
0

Alternatywnie, można mieć specjalną tabelę z liczników. To nie jest dobry wzór projektu, ale daje ci pełną kontrolę nad tym, jak działa tożsamość.

Powiązane problemy