it-swarm-eu.dev

Co je lepší pro velké změny v tabulce: ODSTRANIT a VLOŽIT pokaždé nebo UPDATE existující?

Dělám projekt, kde musím denně měnit kolem 36 000 záznamů v jedné tabulce. Zajímalo by mě, co bude lepší výkon:

  1. odstranit řádky a vložit nové, nebo
  2. aktualizovat již existující řádky

Pro mě je jednodušší smazat všechny řádky a vložit nové, ale pokud to bude fragmentovat tabulku a indexy a dopad na výkon, pak bych raději aktualizoval tam, kde je to možné, a mazal/vkládal pouze v případě potřeby.

Bude se jednat o noční službu a nechci zvyšovat rychlost samotného procesu. Jsem více znepokojen výkonem dotazů proti této tabulce obecně, kde již mám 89 milionů záznamů a jak to ovlivní tento noční proces.

Měl bych vymazat/vložit záznamy nebo mám aktualizovat stávající (pokud je to možné) pro tento noční proces?

27
adopilot

To opravdu záleží na tom, kolik údajů se mění. Řekněme, že tato tabulka obsahuje 20 sloupců. A také máte 5 indexů - každý na rozdíl. sloupec.

Nyní, pokud se hodnoty ve všech 20 sloupcích mění OR, i když se data v 5 sloupcích mění a všech těchto 5 sloupců je indexováno, může být lepší „mazání a vkládání“. Pokud však mění se pouze 2 sloupce a řekněme, že nejsou součástí žádných indexů bez klastru, pak můžete být lepší z „Aktualizace“ záznamů, protože v tomto případě bude aktualizován pouze seskupený index (a indexy nebudou muset být aktualizovány) ).


Při dalším výzkumu jsem zjistil, že výše uvedený komentář je trochu nadbytečný, protože SQL Server interně má 2 samostatné mechanismy pro provádění UPDATE. - „Aktualizace na místě“ (tj. Změnou hodnoty sloupců na novou v původním řádku) nebo jako „ne na místě UPDATE“ (DELETE, poté INSERT).

Pravidlem jsou aktualizace na místě a pokud je to možné, provádějí se. Řádky zde zůstávají přesně na stejném místě na stejné stránce ve stejném rozsahu. Zmapovány jsou pouze ovlivněné bajty. Tlog má pouze jeden záznam (za předpokladu, že neexistují žádné spouštěče aktualizace). Aktualizace se provádějí, pokud se hromada aktualizuje (a na stránce je dostatek místa). Aktualizace se také uskuteční, pokud se změní klastrovací klíč, ale řádek se nemusí vůbec pohybovat.

Například: pokud máte klastrovaný index příjmení a máte jména: Able, Baker, Charlie Nyní chcete aktualizovat Baker na Becker. Žádné řádky se nesmí přesouvat. Může se tak stát na místě. Vzhledem k tomu, pokud musíte aktualizovat možnost Kumar, řádky se budou muset přesunout (i když budou na stejné stránce). V tomto případě provede SQL Server ODSTRANĚNÍ, po kterém následuje INSERT.

Vzhledem k výše uvedenému navrhuji, abyste provedli normální UPDATE a nechali SQL Server přijít na to, jak nejlépe to interně provést.

Pro více informací o interních aktualizacích "UPDATE" nebo v tom případě o jakýchkoli interních interiérech SQL Serveru, podívejte se na knihu Kalen Delaney, Paul Randal a kol. - Interní SQL Server 2008 .

10

Prozkoumali jste příkaz SLOUČIT v SQL 2008? Zde je základní příklad:

  merge YourBigTable ybt
  using (select distinct (RecordID) from YourOtherTable) yot
     on yot.Recordid = YBT.RecordID
  when NOT matched by target
  then  insert (RecordID)
        values (yot.DeviceID) ;

V zásadě jde o příkaz „UPSERT“. Aktualizujte, pokud existuje, vložte jej, pokud není. Velmi rychlý, velmi cool příkaz.

8
datagod

Ale já sám jsem zkontroloval Smazat a Vložit vs Aktualizace na tabulce, která obsahuje 30 milionů záznamů (3crore). Tato tabulka obsahuje jeden seskupený jedinečný složený klíč a 3 nekluzové klíče. Odstranění a vložení trvalo 9 minut. Aktualizace trvalo 55 minut. V každém řádku byl aktualizován pouze jeden sloupec.

Žádám vás, abyste to nehádali. Rovnice se změní, když pracujeme s velkou tabulkou s mnoha sloupci as velkým množstvím dat.

4
srinivas

Aktualizace není tak rychlá. Trik spočívá v dosažení rychlého vložení spočívající v deaktivaci indexů během vkládání dat.

Zvažte použití tohoto:

-- disable indexes
ALTER INDEX [index_name] ON dbo.import_table DISABLE
-- ... disable more indexes

-- don't use delete if you don't care about minimal logging. truncate is faster
TRUNCATE TABLE dbo.import_table

-- just insert the new rows
INSERT dbo.import_table
SELECT
    *
FROM
    dbo.source_table

-- rebuild indexes
ALTER INDEX [index_name] ON dbo.import_table REBUILD
-- ... rebuild more indexes

Ještě rychlejší je také vypnout automatickou aktualizaci statistik v možnostech db. Pokud se tabulka významně změní, měli byste spustit:

UPDATE STATISTICS dbo.import_table

nebo

EXEC sp_updatestats

jako úkol pravidelně (denně, týdně v závislosti na velikosti db), aby byly statistiky aktuální. Věci, na které je třeba dát pozor, je aktualizace statistik, když je tabulka prázdná. Tím se statistika zkomplikuje, pokud je nespustíte po opětovném naplnění tabulky.

3
Asken