sql >> Database teknologi >  >> RDS >> PostgreSQL

Redundante data i opdateringserklæringer

På grund af PostgreSQL MVCC, en UPDATE er faktisk meget som en DELETE plus en INSERT . Med den bemærkelsesværdige undtagelse af ristede værdier - se:

  • Omskriver Postgres hele rækken ved opdatering?

(Og mindre forskelle for heap-tupler - DELETE + INSERT starter en ny HOT-kæde - men det har ingen betydning for sagen ved hånden.)

For at være præcis er den "slettede" række bare usynlig for enhver transaktion, der starter efter sletningen er blevet begået, og støvsuget senere. Derfor er der på databasesiden, inklusive indeksmanipulation, i realiteten ingen forskel mellem de to udsagn. (Undtagelser gælder, fortsæt med at læse.) Det øger netværkstrafikken en smule (afhængigt af dine data) og kræver lidt parsing.

Jeg studerede HOT opdateringer noget mere efter @araqnids input og kørte nogle tests. Opdateringer af kolonner, der ikke faktisk ændrer værdien, gør ingen forskel overhovedet hvad angår HOT opdateringer. Mit svar holder. Se detaljer nedenfor.

Dette gælder også for ristede attributter, da disse heller ikke berøres, medmindre værdierne faktisk ændres .

Men , hvis du bruger udløsere pr. kolonne (introduceret med s. 9.0), kan dette have uønskede bivirkninger!

Jeg citerer manualen om triggere:

... en kommando såsom UPDATE ... SET x = x ... vil udløse en udløser på kolonne x , selvom kolonnens værdi ikke ændrede sig .

Fed fremhævelse mine.

Abstraktionslag er for nemheds skyld. De er nyttige for SQL-analfabeter udviklere, eller hvis applikationen skal være portabel mellem forskellige RDBMS. På den negative side kan de slagte ydeevne og introducere yderligere fejlpunkter. Jeg undgår dem, hvor det er muligt.

HOT (Heap-only tuple) opdateringer

Heap-Only Tuples blev introduceret med Postgres 8.3, med vigtige forbedringer i 8.3.4 og 8.4.9.
Udgivelsesbemærkningerne til Postgres 8.3:

UPDATE s og DELETE s efterlader døde tupler, og det samme gør mislykkede INSERT s.Tidligere kun VACUUM kunne generobre plads taget af døde tupler. WithHOT kan død tupelplads automatisk genvindes på tidspunktet forINSERT eller UPDATE hvis der ikke foretages ændringer i indekserede kolonner . Dette giver mulighed for mere ensartet ydeevne. HOT undgår også at tilføje duplikerede indeksposter.

Understreg min. Og "ingen ændringer" inkluderer tilfælde, hvor kolonner er opdateret med samme værdi, som de allerede har. Jeg testede faktisk , da jeg ikke var sikker.

I sidste ende bekræfter den omfattende README.HOT i kildekoden det.

Ristede søjler står heller ikke i vejen for VARME opdateringer. Den HOT-opdaterede tuple linker blot til de samme, uændrede tuple(r) i toastgaffelen i relationen. HOT opdateringer fungerer endda med ristede værdier i mållisten (faktisk ændret eller ej). Hvis ristede værdier ændres, medfører det naturligvis skrivninger til toast-relationsgaffelen. Jeg testede også alt det.

Tag ikke mit ord for det, se selv. Postgres giver et par funktioner til at tjekke statistik. Kør din UPDATE med og uden alle kolonner og tjek om det gør nogen forskel.

-- Number of rows HOT-updated in table:
SELECT pg_stat_get_tuples_hot_updated('table_name'::regclass::oid)

-- Number of rows HOT-updated in table, in the current transaction:
SELECT pg_stat_get_xact_tuples_hot_updated('table_name'::regclass::oid)

Eller brug pgAdmin. Vælg din tabel og inspicer fanen "Statistik" i hovedvinduet.

Vær opmærksom på, at HOT-opdateringer kun er mulige, når der er plads til den nye tuple-version på samme side af hovedrelationsgaflen. En simpel måde at fremtvinge denne betingelse på er at teste med en lille tabel, der kun rummer nogle få rækker. Sidestørrelsen er typisk 8k, så der skal være ledig plads på siden.



  1. SELECT DISTINCT er langsommere end forventet på mit bord i PostgreSQL

  2. Hvad er PostgreSQL-ækvivalenten for ISNULL()

  3. 3 måder at slette duplikerede rækker i SQL Server, mens du ignorerer den primære nøgle

  4. SQL Server aktive sessioner og status