SQL-server
er bedst til sæt-baserede operationer, mens CASCADE
sletninger er i sagens natur registreringsbaserede.
SQL-server
, i modsætning til de andre servere, forsøger at optimere de øjeblikkelige sæt-baserede operationer, men det virker kun et niveau dybt. Det skal have posterne slettet i tabellerne på øverste niveau for at slette dem i tabellerne på lavere niveau.
Med andre ord fungerer cascading operationer op og ned, mens din løsning arbejder ned og op, hvilket er mere set-baseret og effektivt.
Her er et eksempelskema:
OPRET TABEL t_g (id INT IKKE NULL PRIMÆR NØGLE)OPRET TABEL t_p (id INT IKKE NULL PRIMÆR NØGLE, g INT IKKE NULL, BEGRÆNSNING fk_p_g UDENLANDSKE NØGLE (g) REFERENCER t_g PÅ SLETT CASAT (g) id INT IKKE NULL PRIMÆR NØGLE, p INT IKKE NULL, BEGRÆNSNING fk_c_p UDENLANDSKE NØGLE (p) REFERENCER t_p PÅ SLET CASCADE)CREATE INDEX ix_p_g ON t_p (g)CREATE INDEX ix_c_p ON _code
, denne forespørgsel:
DELETEFROM t_gWHERE id> 50000
og dens plan:
|--Sekvens |--Tabelspole | |--Clustered Index Delete(OBJECT:([test].[dbo].[t_g].[PK__t_g__176E4C6B]), HVOR:([test].[dbo].[t_g].[id]> (50000)) ) |--Index Delete(OBJECT:([test].[dbo].[t_p].[ix_p_g]) MED BESTILLET FORFETCH) | |--Sort(ORDER BY:([test].[dbo].[t_p].[g] ASC, [test].[dbo].[t_p].[id] ASC)) | |--Bordspole | |--Clustered Index Delete(OBJECT:([test].[dbo].[t_p].[PK__t_p__195694DD]) MED BESTILLET FORFØTNING) | |--Sort(ORDER BY:([test].[dbo].[t_p].[id] ASC)) | |--Merge Join(Inner Join, MERGE:([test].[dbo].[t_g].[id])=([test].[dbo].[t_p].[g]), RESIDUAL:( [test].[dbo].[t_p].[g]=[test].[dbo].[t_g].[id])) | |--Bordspole | |--Index Scan(OBJECT:([test].[dbo].[t_p].[ix_p_g]), BESTILLET FREM) |--Index Delete(OBJECT:([test].[dbo].[t_c]. [ix_c_p]) MED BESTILLET FORFETCH) |--Sort(ORDER BY:([test].[dbo].[t_c].[p] ASC, [test].[dbo].[t_c].[id] ASC )) |--Clustered Index Delete(OBJECT:([test].[dbo].[t_c].[PK__t_c__1C330188]) MED BESTILLET FORFETCH) |--Tabelspole |--Sort(ORDER BY:([test]. [dbo].[t_c].[id] ASC)) |--Hash Match(Indre Join, HASH:([test].[dbo].[t_p].[id])=([test].[dbo] ].[t_c].[p])) |--Tabelspole |--Index Scan(OBJECT:([test].[dbo].[t_c].[ix_c_p]), BESTILLET VIDERE)
Først SQL-server
sletter poster fra t_g
, og forbinder derefter de slettede poster med t_p
og sletter fra sidstnævnte, slutter sig til poster slettet fra t_p
med t_c
og sletter fra t_c
.
En enkelt tre-bords joinforbindelse ville være meget mere effektiv i dette tilfælde, og det er, hvad du gør med din løsning.
Hvis det får dig til at føle dig bedre, Oracle
optimerer ikke kaskadeoperationer på nogen måde:de er altid NESTED LOOPS
og Gud hjælpe dig, hvis du har glemt at oprette et indeks i referencekolonnen.