0

Ich habe eine Tabelle (sagen Tabelle1), deren Primärschlüssel Fremdschlüssel Beziehung mit 10 anderen Tabellen hat. Alle diese Tabellen haben Millionen von Daten. Ich müsste alle verwaisten Datensätze aus Table1 in einer leistungsfähigen Weise löschen. Außerdem sollte das Skript keine Schreibvorgänge für diese Tabellen blockieren. Kann mir jemand mit der Frage helfenOrphan Records aus einer Tabelle löschen

ich SQL Server bin mit 2014

+0

Ich bin auf der Suche nach einem leistungsoptimierten Skript –

+0

Sie könnten in Zukunft DELETE CASCADE-Beziehungen berücksichtigen. Dies würde es Ihnen ermöglichen, aus 'Table1' zu löschen, ohne zuerst die" 10 anderen Tabellen "-Daten zu entfernen. Das Löschen auf der Primärdatenbank würde sich dann durch die zugehörigen Tabellen fortpflanzen und die Zeilen entfernen, auf die die gelöschten Primärzeilen von "Table1" verweisen. – Kritner

+0

Mögliches Duplikat von [Wie verwaiste Datensätze aus der zweiten Tabelle löschen] (http://stackoverflow.com)/questions/27963398/how-to-delete-verwaiste-records-from-second-table) –

Antwort

0

Dies ist, was ich jetzt versuchen:

SET NOCOUNT ON 

DECLARE @totalcnt INT 
     ,@Batch INT = 1000 

IF OBJECT_ID('tempdb..#TEMPWrk') IS NOT NULL 
    DROP TABLE #TEMPWrk 

IF OBJECT_ID('tempdb..#TEMP') IS NOT NULL 
    DROP TABLE #TEMP 

CREATE TABLE #TEMP (TableKey int NOT NULL PRIMARY KEY) 
CREATE TABLE #TEMPWrk (TableKey int NOT NULL PRIMARY KEY) 

INSERT INTO #TEMP 
SELECT 
    A.TableKey 
FROM 
    dbo.Table1 A 
     LEFT JOIN (
        SELECT TableKey FROM dbo.Table2 UNION 
        SELECT TableKey FROM dbo.Table3 UNION 
        SELECT TableKey FROM dbo.Table4 UNION 
        SELECT TableKey FROM dbo.Table5 UNION 
        SELECT TableKey FROM dbo.Table6 UNION 
        SELECT TableKey FROM dbo.Table7 UNION 
        SELECT TableKey FROM dbo.Table8 
        ) T ON T.TableKey = A.TableKey 
WHERE 
    T.TableKey IS NULL 


SELECT 
    @totalcnt = COUNT(*) 
FROM 
    #TEMP 

WHILE (@totalcnt > 0) 
BEGIN 
    PRINT @totalcnt 
    DELETE TOP (@batch) 
    FROM 
     #TEMP 
    OUTPUT DELETED.TableKey INTO #TEMPWrk 

    DELETE T 
    FROM 
     dbo.Table1 T 
      JOIN #TEMPWrk A ON T.TableKey = A.TableKey 

    DELETE FROM #TEMPWrk 

    SELECT 
     @totalcnt = COUNT(*) 
    FROM 
     #TEMP 
END 

SET NOCOUNT OFF 
0

Ich habe ähnliche Löschungen wie folgt:

  1. auf dem Löschen von Tabellen gruppierten Index Key identifizieren und in Chargen von 10k auf 100k löschen basierend auf dem Hardwareszenario.
  2. Wenn Sie Trigger, CT, CDC, indizierte Sichten für diese Tabellen haben, müssen wir während des Löschvorgangs löschen oder deaktivieren, wodurch Löschvorgänge schneller werden.
  3. Ich habe 'Wiederherstellungsmodus' SIMPLE während des Löschvorgangs gemacht.
  4. Explizite "Checkpoint" während einiger Löschungen aufgerufen.

Für ein gegebenes Szenario, wenn es nicht erlaubt ist eine der oben genannten Schritte in PROD zu tun, dann Online löschen wird langsamer sein bzw.

0

Da Transaktionen in beiden Tabellen sind und die Verriegelung zu minimieren, können Sie sich bewerben das Prinzip Teile und herrsche

1- max die ID von Tabelle 1 (der Elterntabelle) erhalten

2- das folgende Skript in Stufen, beispielsweise 100000 Zeile pro Iteration

DELETE FROM tabl2 t2 
WHERE t2.id < 100000 
AND t2.id IN (SELECT t1.id FROM table1 t1) 

3- Wiederholung Schritt 2 für anderen Bereich

where t2.id BETWEEN 100001 AND 200000 

bis max id

Sie können diese Schritte automatisieren mit while-Anweisung

Verwandte Themen