Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Най-бързият начин за актуализиране на 120 милиона записа

Единственият разумен начин за актуализиране на таблица от 120M записа е с SELECT изявление, което попълва секунда маса. Трябва да внимавате, когато правите това. Инструкции по-долу.

Прост случай

За таблица без клъстериран индекс, по време на време без едновременен DML:

  • SELECT *, new_col = 1 INTO clone.BaseTable FROM dbo.BaseTable
  • пресъздаване на индекси, ограничения и т.н. в нова таблица
  • превключване на старо и ново с ПРОМЕНЯНЕ НА СХЕМАТА ... ПРЕХВЪРЛЯНЕ.
  • пуснете старата маса

Ако не можете да създадете клонирана схема, друго име на таблица в същата схема ще свърши работа. Не забравяйте да преименувате всичките си ограничения и задействания (ако е приложимо) след превключвателя.

Непрост калъф

Първо, създайте отново вашата BaseTable със същото име под различна схема, напр. clone.BaseTable . Използването на отделна схема ще опрости процеса на преименуване по-късно.

  • Включете клъстерирания индекс , ако е приложимо. Не забравяйте, че първичните ключове и уникалните ограничения може да са групирани, но не непременно.
  • Включете колони за идентичност и изчислени колони , ако е приложимо.
  • Включете новата си колона INT , където и да му е мястото.
  • Не включвайте някое от следните:
    • задействания
    • ограничения на външния ключ
    • неклъстерни индекси/първични ключове/уникални ограничения
    • проверете ограниченията или ограниченията по подразбиране. Стандартните стойности нямат голяма разлика, но ние се опитваме да поддържаме нещата минимални.

След това тествайте вложката си с 1000 реда:

-- assuming an IDENTITY column in BaseTable
SET IDENTITY_INSERT clone.BaseTable ON
GO
INSERT clone.BaseTable WITH (TABLOCK) (Col1, Col2, Col3)
SELECT TOP 1000 Col1, Col2, Col3 = -1
FROM dbo.BaseTable
GO
SET IDENTITY_INSERT clone.BaseTable OFF

Разгледайте резултатите. Ако всичко се появи в ред:

  • съкратете таблицата за клониране
  • уверете се, че базата данни е в групово регистриран или прост модел за възстановяване
  • извършете пълното вмъкване.

Това ще отнеме известно време, но не толкова дълго, колкото актуализация. След като приключи, проверете данните в таблицата за клониране, за да се уверите, че всичко е правилно.

След това създайте отново всички неклъстерирани първични ключове/уникални ограничения/индекси и ограничения на външния ключ (в този ред). Създайте отново по подразбиране и проверете ограниченията, ако е приложимо. Създайте отново всички тригери. Създайте отново всяко ограничение, индекс или тригер в отделна партида. напр.:

ALTER TABLE clone.BaseTable ADD CONSTRAINT UQ_BaseTable UNIQUE (Col2)
GO
-- next constraint/index/trigger definition here

Накрая преместете dbo.BaseTable към схема за архивиране и clone.BaseTable към схемата dbo (или където се предполага, че вашата маса трябва да живее).

-- -- perform first true-up operation here, if necessary
-- EXEC clone.BaseTable_TrueUp
-- GO
-- -- create a backup schema, if necessary
-- CREATE SCHEMA backup_20100914
-- GO
BEGIN TRY
  BEGIN TRANSACTION
  ALTER SCHEMA backup_20100914 TRANSFER dbo.BaseTable
  -- -- perform second true-up operation here, if necessary
  -- EXEC clone.BaseTable_TrueUp
  ALTER SCHEMA dbo TRANSFER clone.BaseTable
  COMMIT TRANSACTION
END TRY
BEGIN CATCH
  SELECT ERROR_MESSAGE() -- add more info here if necessary
  ROLLBACK TRANSACTION
END CATCH
GO

Ако трябва да освободите дисково пространство, можете да пуснете оригиналната си таблица в този момент, въпреки че може да е разумно да я запазите още известно време.

Излишно е да казвам, че в идеалния случай това е офлайн операция. Ако имате хора, които променят данни, докато извършвате тази операция, ще трябва да извършите операция за вярно с превключвателя на схемата. Препоръчвам да създадете тригер на dbo.BaseTable за да регистрирате всички DML в отделна таблица. Активирайте този тригер, преди да започнете вмъкването. След това в същата транзакция, в която извършвате прехвърлянето на схема, използвайте таблицата на журнала, за да извършите проверка. Тествайте това първо върху подмножество от данни! Делтите са лесни за прецакане.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL Server SELECT в съществуваща таблица

  2. Какво е @@MAX_PRECISION в SQL Server?

  3. Гениална помощна програма за промяна на SQL парола за нулиране на SQL парола

  4. Използвайте DB_ID(), за да върнете идентификатора на база данни в SQL Server

  5. Срокове за събиране на аларми от Spotlight Cloud