2012. augusztus 21., kedd

Update csavarral


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:
  1. 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).

  1. WITH Ranking AS  
  2. (  
  3. SELECT  
  4.       nRank  
  5.       ,ROW_NUMBER() OVER (ORDER BY nHeight) AS nComputedRank  
  6. FROM  
  7.       Buildings  
  8. )  
  9.   
  10. UPDATE  
  11.       Ranking  
  12. SET  
  13.       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.

2 megjegyzés:

  1. hmm, érdekes gondolat az indexelt temp tábla... ezt meg kell vizsgálnom jobban... :)

    VálaszTörlés
  2. Igazsá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.

    Na, 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. :)

    VálaszTörlés