Mi a történik akkor,
ha egy tábla rekordjait rangsorolnám, és ezt a rangsort rögzíteném is a tábla
egy új
oszlopában? Mondjuk így:
- UPDATE Buildings SET nRank = ROW_NUMBER() OVER (ORDER BY nHeight);
Ez történik:
Windowed functions can only appear in
the SELECT or ORDER BY clauses.
Szóval csak SELECT vagy ORDER BY. Szerencsére ez nem olyan
nagy gond. Használhatunk CTE-t, beágyazott query-t vagy view-t, és már
teljesítettük is a fenti megkötést. Hogy pontosan hogyan, az ebből a
script-sorból kiderül. A CTE-s verziót be is kopizom ide (szerintem ez a
legelegánsabb).
- WITH Ranking AS
- (
- SELECT
- nRank
- ,ROW_NUMBER() OVER (ORDER BY nHeight) AS nComputedRank
- FROM
- Buildings
- )
- UPDATE
- Ranking
- SET
- nRank = nComputedRank;
Nagy rekordszám esetén érdemes elgondolkodni egy indexelt
temp tábla használatán. A lemezre írásnak ugyan van költsége, de lehet, hogy
ezt az indexek miatt bőven behozzuk az update-nél.
hmm, érdekes gondolat az indexelt temp tábla... ezt meg kell vizsgálnom jobban... :)
VálaszTörlésIgazság szerint csak egy elmélet volt, de a hozzászólás hatására elkezdtem tesztelgetni. Először kreáltam egy 10M soros, de karcsú táblát, ami kicsit kevesebb lett, mint 400MB. Utána nekiláttam updatelni CTE-n és temp táblán keresztül is, de a CTE mindig elkente a nehézkes "kiírom, visszafrissíteni" módszer száját. Indexek számtalan variációját próbáltam, és a temporary tábla mindig alulmaradt.
VálaszTörlésNa, gondoltam, kicsi még a tábla. Feltornáztam 100M sorra, 4GB-ra (az adott gépben feleennyi RAM van). Azóta túl vagyok néhány végtelennek tűnő rollback-en, két fagyáson és egy a "C meghajtón túl kevés a hely (3MB)" típusú mókán. Ettől még azt gondolom, hogy azon a ponton túl, ahol a rangsorolt rekordszet kifut a memóriából, a temp (vagy fix) táblák lesznek a nyerők, de ennek nem sok köze van az indexekhez.
Ha kicsit felszívom magam, nekimegyek még egyszer. :)