sql >> Databáze >  >> RDS >> Database

Mýty o výkonu:Zkrácení nelze vrátit zpět

Autor hosta :Derik Hammer (@SQLHammer)


Rozdíly mezi TRUNCATE TABLE a DELETE jsou často nepochopeny. Snažím se vyvrátit mýtus, že TRUNCATE TABLE nelze vrátit zpět:

„TRUNCATE TABLE není protokolována, a proto ji nelze vrátit zpět. Pokud jste v transakci, musíte použít DELETE.“

Čtení návodu

Článek Books Online na TRUNCATE TABLE je poměrně popisný:

„Odebere všechny řádky z tabulky nebo zadaných oddílů tabulky, aniž by protokoloval odstranění jednotlivých řádků. TRUNCATE TABLE je podobná příkazu DELETE bez klauzule WHERE; ale TRUNCATE TABLE je rychlejší a využívá méně prostředků systému a transakčního protokolu.“

Skutečnost, že TRUNCATE TABLE používá méně prostředky protokolu transakcí znamená, že do určité míry zapisuje do protokolu transakcí. Pojďme zjistit, kolik a prozkoumat jeho schopnost být vrácena zpět.

Dokažte to

V dřívějším příspěvku to Paul Randal podrobně probírá, ale myslel jsem si, že by bylo užitečné poskytnout velmi jednoduché opakování, aby se vyvrátily oba prvky tohoto mýtu.

Lze TRUNCATE TABLE vrátit zpět?

Dokázat, že TRUNCATE TABLE lze vrátit zpět, je dostatečně snadné. Jednoduše vložím TRUNCATE TABLE do transakce a vrátím ji zpět.

USE demo;
BEGIN TRANSACTION;
  SELECT COUNT(*) [StartingTableRowCount] FROM [dbo].[Test];
  TRUNCATE TABLE [dbo].[Test];
  SELECT COUNT(*) [TableRowCountAfterTruncate] FROM [dbo].[Test];
ROLLBACK TRANSACTION;
SELECT COUNT(*) [TableRowCountAfterRollback] FROM [dbo].[Test];

V tabulce je 100 000 řádků a po vrácení se vrátí na 100 000 řádků:

Zapisuje TRUNCATE TABLE do protokolu?

Provedením CHECKPOINT získáme čistý výchozí bod. Poté můžeme zkontrolovat záznamy protokolu před a za TABLE ZKRÁTENÍ.

USE demo;
CHECKPOINT;
 
  SELECT COUNT(*) [StartingLogRowCount]
  FROM sys.fn_dblog (NULL, NULL);
 
  TRUNCATE TABLE [dbo].[Test];
 
  SELECT COUNT(*) [LogRowCountAfterTruncate]
  FROM sys.fn_dblog (NULL, NULL);

Náš příkaz TRUNCATE TABLE vygeneroval 237 záznamů protokolu (alespoň zpočátku). To je to, co nám umožňuje provést vrácení zpět a jak SQL Server nejprve zaregistruje změnu.

A co DELETE?

Pokud DELETE i TRUNCATE TABLE zapisují do protokolu a lze je vrátit zpět, čím se liší?

Jak je uvedeno v odkazu BOL výše, TRUNCATE TABLE vyžaduje méně prostředků systému a protokolu transakcí. Již jsme si všimli, že pro příkaz TRUNCATE TABLE bylo zapsáno 237 záznamů protokolu. Nyní se podívejme na DELETE.

USE demo;
CHECKPOINT;
 
  SELECT COUNT(*) [StartingLogRowCount]
  FROM sys.fn_dblog (NULL, NULL);
 
  DELETE FROM [dbo].[Test];
 
  SELECT COUNT(*) [LogRowCountAfterDelete]
  FROM sys.fn_dblog (NULL, NULL);

S více než 440 000 záznamy protokolu zapsanými pro DELETE je příkaz TRUNCATE jednoznačně mnohem efektivnější.

Shrnutí

TRUNCATE TABLE je zaprotokolovaný příkaz a lze jej vrátit zpět s obrovskou výkonnostní výhodou oproti ekvivalentnímu DELETE. DELETE je důležité, když chcete odstranit méně řádků, než existuje v tabulce (protože TRUNCATE TABLE nepřijímá klauzuli WHERE). Některé nápady, jak zefektivnit DELETE, najdete v příspěvku Aarona Bertranda „Rozdělit velké operace mazání na kousky.“

O autorovi

Derik je datový profesionál a čerstvě vytvořený Microsoft Data Platform MVP se zaměřením na SQL Server. Jeho vášeň se zaměřuje na vysokou dostupnost, obnovu po havárii, nepřetržitou integraci a automatizovanou údržbu. Jeho zkušenosti zahrnují dlouhodobou administraci databází, poradenství a podnikání ve finančním a zdravotnickém průmyslu. V současné době je Senior Database Administrator zodpovědný za tým Database Operations ve světovém ústředí Subway Franchise. Když není na hodinách nebo nepíše na SQLHammer.com, věnuje Derik svůj čas #sqlfamily jako vedoucí kapitoly uživatelské skupiny FairfieldPASS SQL Server ve Stamfordu, CT.
  1. VLOŽTE ... PŘI AKTUALIZACI DUPLIKÁTNÍHO KLÍČE s KDE?

  2. Počítání počtu výskytů znaku v Oracle SQL

  3. Funkce hodnocení v MySQL

  4. Chyba při použití kromě v dotazu