Avatar billede donkazz Nybegynder
28. december 2007 - 10:09 Der er 12 kommentarer og
2 løsninger

Smarteste måde at opdatere flere hundredetusinde rækker på?

Hejsa!

Jeg har en tabel, som indeholder ca. 300.000 rækker. Hver række er tilknyttet et userId, som henviser til en anden tabel, nemlig brugertabellen.
Nu skal jeg så skrotte brugertabellen, da jeg har lavet en ANDEN brugertabel. De samme brugere findes i den nye tabel, blot med andre unikke id'er, så jeg skal på en eller anden måde have opdateret de 300.000 rækker til at passe på de nye id'er. ER der en snedig måde at gøre det på?
Umiddelbart ville jeg lave et udtræk i ASP og så loope igennem alle rækkerne, og så bruge en select case hvor jeg ser på det nuværende id, og så opdaterer rækken i forhold til hvad det skal være i stedet, men man skal ikke være meget skarp for at se at det godt kan blive en noget resourcekrævende operation, samt at faren for timeout jo så er der, hvilket ville være ret ærgeligt, skulle det ske midt i loopet..

What to do?
Avatar billede keysersoze Guru
28. december 2007 - 10:35 #1
hvis du - som kategorien du har lagt spm i antyder - kører med mssql så hold asp langt væk fra denne operation. lav i stedet en stored procedure med mere eller mindre samme opbygning som du ville have gjort i asp (altså formentlig et loop) og pak det hele ind i en transaction så du kan køre rollback ved fejl.
Avatar billede donkazz Nybegynder
28. december 2007 - 10:41 #2
Jeg forstod "stored procedure".. :-D

Kan du hjælpe mig lidt på vej? Hvad er en transaction i fagsprog?

Jeg har ingen anelse om hvordan jeg skal opbygge den stored procedure, jeg er mest vant til select from where ;-)
Avatar billede keysersoze Guru
28. december 2007 - 10:59 #3
en transation er et slags alt eller intet scenarie - enten går alt godt (og databasen opdateres) eller også sker der slet ingenting (dvs ingen ændring af data indenfor transactionen). fx sådan (der er dog flere måder at stille det op på);

BEGIN TRY
  BEGIN TRANSACTION
    'DO THE WORK
    COMMIT TRANSACTION
END TRY

BEGIN CATCH
    ROLLBACK TRANSACTION
END CATCH

En stored procedure i dit tilfælde vil nok ligne meget asp'en - du skal formentlig selecte fra en tabel (alm sql), lave et loop (lidt anderledes end asp), inserte data (alm sql), udtrække nyt id (alm sql) og update en anden tabel (alm sql). Tag en søgning på google og få lidt idé omkring opbygningen - så prøv at lav din SP og vend tilbage med evt spm :)
Avatar billede donkazz Nybegynder
28. december 2007 - 13:55 #4
Nu har jeg siddet og luret på nettet, men jeg kan kun finde eksempler der looper igennem en tabel med en @counter, men på den måde kan jeg jo ikke selecte på rækkerne, da deres unikke id'er jo ikke nødvendigvis er fortløbende, f.eks. hvis der er slettet en række hist og pist...?
Avatar billede hrc Mester
28. december 2007 - 14:52 #5
Du skal lave en cursor. Med den kan du loope gennem din gamle brugertabel som var det en for-next tingest. I øvrigt bør du nok krympe din log-tabel efter sådan en voluminøs operation. En stor (transaktions)log-fil er sløver din database og kan give "underlige" svartider; sådan en fil skal holdes nede.

Her et link (et godt link kan ikke gentages for tit) til TSQL 2005:

  http://msdn2.microsoft.com/en-us/library/ms189826.aspx

Mere specifikt skal du ind i dette link for at lære om cursorere:

  http://msdn2.microsoft.com/en-us/library/ms190498.aspx
  http://msdn2.microsoft.com/en-us/library/ms180169.aspx

(der er eksempler i bunden)

Humlen er dette:
DECLARE vend_cursor CURSOR
FOR SELECT * FROM Purchasing.Vendor
OPEN vend_cursor
FETCH NEXT FROM vend_cursor
.. de glemte at vise at den også skal lukkes
Avatar billede arne_v Ekspert
28. december 2007 - 15:15 #6
Umiddelbart tænker jeg jo:

UPDATE stortabel SET stortabel.brugerid = (SELECT nybrugertabel.brugerid
FROM nybrugertabel,gammelbrugertabel
WHERE nybrugertabel.brugernavn=gammelbrugertabel.brugernavn AND gammelbrugertabel.brugerid=stortabel.brugerid)

Og enten lave det i en transktion eller på en kopi af den store tabel.
Avatar billede hrc Mester
28. december 2007 - 23:10 #7
Man kan selvfølgeligt også bare lave det simpelt... Arnes eksempel skal nok virke (mon ikke han har prøvet det før?).
Avatar billede arne_v Ekspert
29. december 2007 - 03:20 #8
Jeg må bryde sammen og tilstå at jeg ikke har prøvet det af inden jeg postede.

Men jeg tror på ideen.
Avatar billede arne_v Ekspert
21. januar 2008 - 04:40 #9
donkazz ?
Avatar billede donkazz Nybegynder
21. januar 2008 - 15:32 #10
Ja jeg forstod ikke meget af alt det her, men jeg må sætte mig mere ind i det via. de links I har givet mig når den store flyttedag kommer. :)

Tak for hjælpen, drop nogle svar, så ryger der points af til jer..

og undskyld den lange responstid, I ved vel hvordan det er når kuglerne flyver rundt om hovedet
Avatar billede hrc Mester
21. januar 2008 - 22:33 #11
Er jeg med i pointsene?
Avatar billede donkazz Nybegynder
21. januar 2008 - 22:37 #12
ja da... det er jo dine links jeg skal læse op på når jeg engang har luft i hovedet ;)
Avatar billede arne_v Ekspert
21. januar 2008 - 22:49 #13
hvis den simple UPDATE virker
Avatar billede donkazz Nybegynder
22. januar 2008 - 09:46 #14
Håber det er fair pointdeling, ellers må jeg skylde i banken ;)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester