Δεν υπάρχει τρόπος να διαγράψει κανείς εγγραφές χωρίς να καταγραφούν στο transaction log, εκτός και αν εκτελέσει το truncate table. Ο λόγος είναι ότι οι αλλαγές στον SQL Server (αλλά και κάθε άλλη βάση) καταγράφονται πάντα για να αποφευχθεί η περίπτωση να "κτυπήσει" η βάση την ώρα που καταχωρεί τις αλλαγές στο σκληρό και στις εσωτερικές δομές του. Διαφορετικά,θα υπήρχε κίνδυνος να διαγραφεί μια γραμμή αλλά να φαίνεται σαν γεμάτη ή το αντίστροφο.
Για να μπορέσει κανείς να τροποποιήσει μαζικά πολλές εγγραφές (update, delete) αποφεύγοντας να γεμίσει το transaction log και να κλειδώσει τους άλλους χρήστες ενός πίνακα υπάρχουν μερικοί τρόποι.
- Μία λύση είναι να χρησιμοποιήσει ένα static cursor που θα επιστρέφει τα ID των εγγραφών που χρειάζεται να τροποποιηθούν και μέσα στον cursor να εκτελεί τα update/delete. Είναι ίσως μία από τις ελάχιστες φορές που έχει νόημα να χρησιμοποιηθεί ένα cursor. Δεν είναι βέβαια και τόσο γρήγορη λύση επειδή καταλήγει σε πολλές εκτελέσεις του update/delete.
- Μια άλλη λύση είναι να σπάσει το delete ή update σε batches χρησιμοποιώντας την εντολή SET ROWCOUNT.
SET ROWCOUNT 1000
WHILE (1=1) BEGIN
BEGIN TRANSACTION
UPDATE...set ...,MyLastUpdate='date',...WHERE
MyLastUpdate < 'date'
-- Update 1000 nonupdated rows
IF @@ROWCOUNT = 0
BEGIN
COMMIT TRANSACTION
BREAK
END
COMMIT TRANSACTION
END
Τέλος, η ταχύτητα μπορεί να βελτιωθεί αν το update/delete query περιέχει κάποιο FROM χρησιμοποιώντας table hints όπως το NOLOCK.
Παναγιώτης Καναβός, Freelancer
Twitter: http://www.twitter.com/pkanavos