Delete database objects in batches
authorMatthias Schmidt <gravatronics@live.com>
Sat, 22 Jun 2019 12:09:39 +0000 (14:09 +0200)
committerMatthias Schmidt <gravatronics@live.com>
Sat, 22 Jun 2019 12:09:39 +0000 (14:09 +0200)
wcfsetup/install/files/lib/data/DatabaseObjectEditor.class.php

index 458b822807f56ed6c951c56af915e40d859dfd7c..1dfa9c0ef6508f17ba2a46194a5749e6095c96f9 100644 (file)
@@ -100,14 +100,22 @@ abstract class DatabaseObjectEditor extends DatabaseObjectDecorator implements I
         * @inheritDoc
         */
        public static function deleteAll(array $objectIDs = []) {
-               $sql = "DELETE FROM     ".static::getDatabaseTableName()."
-                       WHERE           ".static::getDatabaseTableIndexName()." = ?";
-               $statement = WCF::getDB()->prepareStatement($sql);
-               
                $affectedCount = 0;
+               
+               // 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([$objectID]);
+               for ($i = 0; $i < $batchCount; $i++) {
+                       $batchObjectIDs = array_slice($objectIDs, $i * $itemsPerLoop, $itemsPerLoop);
+                       
+                       $sql = "DELETE FROM     " . static::getDatabaseTableName() . "
+                               WHERE           " . static::getDatabaseTableIndexName() . 
+                                               " IN (?" . str_repeat(', ?', count($batchObjectIDs) - 1) . ")";
+                       $statement = WCF::getDB()->prepareStatement($sql);
+                       $statement->execute($batchObjectIDs);
                        $affectedCount += $statement->getAffectedRows();
                }
                WCF::getDB()->commitTransaction();