Delete edit history entries in batches
authorMatthias Schmidt <gravatronics@live.com>
Sat, 22 Jun 2019 08:31:53 +0000 (10:31 +0200)
committerMatthias Schmidt <gravatronics@live.com>
Sat, 22 Jun 2019 08:31:53 +0000 (10:31 +0200)
This change speeds up `EditHistoryManager::delete()` by more than 80% in my test cases ranging from deleting 100 to up to 100 000 entries.

wcfsetup/install/files/lib/system/edit/EditHistoryManager.class.php

index 2f8dab73a0390458ca590174798d8c067a1e7977..663881a3e4724ca554771e59507f5752ffad99cf 100644 (file)
@@ -77,13 +77,20 @@ class EditHistoryManager extends SingletonFactory {
        public function delete($objectType, array $objectIDs) {
                $objectTypeID = $this->getObjectTypeID($objectType);
                
-               $sql = "DELETE FROM     wcf".WCF_N."_edit_history_entry
-                       WHERE           objectTypeID = ?
-                               AND     objectID = ?";
-               $statement = WCF::getDB()->prepareStatement($sql);
+               // instead of executing one query per object id, execute queries
+               // for batches of up to 1000 object ids at once
+               $itemsPerLoop = 1000;
+               $batchCount = ceil(count($objectIDs) / $itemsPerLoop);
+               
                WCF::getDB()->beginTransaction();
-               foreach ($objectIDs as $objectID) {
-                       $statement->execute([$objectTypeID, $objectID]);
+               for ($i = 0; $i < $batchCount; $i++) {
+                       $batchObjectIDs = array_slice($objectIDs, $i * $itemsPerLoop, $itemsPerLoop);
+                       
+                       $sql = "DELETE FROM     wcf".WCF_N."_edit_history_entry
+                               WHERE           objectTypeID = ?
+                                               AND objectID IN (?" . str_repeat(', ?', count($batchObjectIDs) - 1) . ")";
+                       $statement = WCF::getDB()->prepareStatement($sql);
+                       $statement->execute(array_merge([$objectTypeID], $batchObjectIDs));
                }
                WCF::getDB()->commitTransaction();
        }