sql >> Databáze >  >> RDS >> Sqlserver

Přírůstek identity skáče v databázi SQL Server

S tímto chováním se setkáváte kvůli zlepšení výkonu od SQL Server 2012.

Nyní ve výchozím nastavení používá velikost mezipaměti 1 000 při přidělování IDENTITY hodnoty pro int a restartování služby může „ztratit“ nepoužívané hodnoty (velikost mezipaměti je 10 000 pro bigint /numeric ).

Toto je uvedeno v dokumentaci

SQL Server může z důvodů výkonu ukládat hodnoty identity do mezipaměti a některé z přiřazených hodnot mohou být ztraceny během selhání databáze nebo restartu serveru. To může mít za následek mezery v hodnotě identity po vložení. Pokud mezery nejsou přijatelné, pak by aplikace měla použít svůj vlastní mechanismus pro generování klíčových hodnot. Použití generátoru sekvencí s NOCACHE Tato možnost může omezit mezery na transakce, které nejsou nikdy zavázány.

Z údajů, které jste ukázali, to vypadá, že se to stalo po zadání dat 22. prosince, pak si při restartu SQL Server rezervoval hodnoty 1206306 - 1207305 . Po zadání dat pro 24. – 25. prosince byl proveden další restart a SQL Server rezervoval další rozsah 1207306 - 1208305 viditelné v záznamech pro 28.

Dokud nerestartujete službu s neobvyklou frekvencí, žádné „ztracené“ hodnoty pravděpodobně neudělají žádnou významnou díru v rozsahu hodnot povolených datovým typem, takže nejlepší zásadou je nestarat se o to.

Pokud je to pro vás z nějakého důvodu skutečný problém, některá možná řešení jsou...

  1. Můžete použít SEQUENCE místo sloupce identity a definujte například menší velikost mezipaměti a použijte NEXT VALUE FOR ve výchozím nastavení sloupce.
  2. Nebo použijte příznak trasování 272, který vytvoří IDENTITY alokace přihlášená jako ve verzích do 2008 R2. To platí globálně pro všechny databáze.
  3. Nebo u nejnovějších verzí spusťte ALTER DATABASE SCOPED CONFIGURATION SET IDENTITY_CACHE = OFF zakázat ukládání identity do mezipaměti pro konkrétní databázi.

Měli byste vědět, že žádné z těchto řešení nezaručuje žádné mezery. IDENTITY to nikdy nezaručilo jak by to bylo možné pouze serializací příloh do tabulky. Pokud potřebujete sloupec bez mezer, budete muset použít jiné řešení než IDENTITY nebo SEQUENCE



  1. Jak funguje ASCII() v MariaDB

  2. Postgres nepoužívá index, když je mnohem lepší volba index scan

  3. Jaký je nejlepší způsob implementace Polymorphic Association na SQL Server?

  4. Protokol transakcí serveru SQL – část 1