From 3663a15329b1ac2c140caf75759f28797ffa9241 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Wed, 15 May 2013 17:37:06 +0200 Subject: [PATCH] Import of language variables is now 5 times faster on MySQL --- .../data/language/LanguageEditor.class.php | 88 +++++-------------- 1 file changed, 21 insertions(+), 67 deletions(-) diff --git a/wcfsetup/install/files/lib/data/language/LanguageEditor.class.php b/wcfsetup/install/files/lib/data/language/LanguageEditor.class.php index 204b3d389c..877ca5cd85 100644 --- a/wcfsetup/install/files/lib/data/language/LanguageEditor.class.php +++ b/wcfsetup/install/files/lib/data/language/LanguageEditor.class.php @@ -199,7 +199,7 @@ class LanguageEditor extends DatabaseObjectEditor implements IEditableCachedObje } // loop through categories to import items - $items = array(); + $itemData = array(); foreach ($categories as $category) { $categoryName = $category->getAttribute('name'); $categoryID = $usedCategories[$categoryName]; @@ -210,76 +210,30 @@ class LanguageEditor extends DatabaseObjectEditor implements IEditableCachedObje $itemName = $element->getAttribute('name'); $itemValue = $element->nodeValue; - $items[$itemName] = array( - 'name' => $itemName, - 'value' => $itemValue, - 'categoryID' => $categoryID - ); + $itemData[] = $this->languageID; + $itemData[] = $itemName; + $itemData[] = $itemValue; + $itemData[] = $categoryID; + if ($packageID) $itemData[] = $packageID; } } - if (!empty($items)) { - $existingItems = $statementParameters = array(); - - // find existing items - $itemList = new LanguageItemList(); - $itemList->getConditionBuilder()->add("language_item.languageItem IN (?)", array(array_keys($items))); - $itemList->getConditionBuilder()->add("language_item.languageID = ?", array($this->languageID)); - $itemList->readObjects(); - - foreach ($itemList->getObjects() as $languageItem) { - $existingItems[$languageItem->languageItem] = $languageItem; - } - - foreach ($items as $item) { - if (isset($existingItems[$item['name']])) { - // update existing item - $itemEditor = new LanguageItemEditor($existingItems[$item['name']]); - $itemEditor->update(array( - 'languageItemValue' => $item['value'], - 'languageCategoryID' => $item['categoryID'], - 'languageUseCustomValue' => 0, - 'languageItem' => $item['name'] - )); - } - else { - // store item for later insert - $statementParameters[] = $item; - } - } - - if (!empty($statementParameters)) { - if ($packageID) { - $sql = "INSERT INTO wcf".WCF_N."_language_item + if (!empty($itemData)) { + // insert/update a maximum of 50 items per run (prevents issues with max_allowed_packet) + $step = ($packageID) ? 5 : 4; + for ($i = 0, $length = count($itemData); $i < $length; $i += 50 * $step) { + $parameters = array_slice($itemData, $i, 50 * $step); + $repeat = count($parameters) / $step; + + $sql = "INSERT INTO wcf".WCF_N."_language_item (languageID, languageItem, languageItemValue, languageCategoryID, packageID) - VALUES (?, ?, ?, ?, ?)"; - $statement = WCF::getDB()->prepareStatement($sql); - - foreach ($statementParameters as $item) { - $statement->execute(array( - $this->languageID, - $item['name'], - $item['value'], - $item['categoryID'], - $packageID - )); - } - } - else { - $sql = "INSERT INTO wcf".WCF_N."_language_item - (languageID, languageItem, languageItemValue, languageCategoryID) - VALUES (?, ?, ?, ?)"; - $statement = WCF::getDB()->prepareStatement($sql); - - foreach ($statementParameters as $item) { - $statement->execute(array( - $this->languageID, - $item['name'], - $item['value'], - $item['categoryID'] - )); - } - } + VALUES ".substr(str_repeat('(?, ?, ?, ?'. ($packageID ? ', ?' : '') .'), ', $repeat), 0, -2)." + ON DUPLICATE KEY + UPDATE languageItemValue = VALUES(languageItemValue), + languageCategoryID = VALUES(languageCategoryID), + languageUseCustomValue = 0"; + $statement = WCF::getDB()->prepareStatement($sql); + $statement->execute($parameters); } } -- 2.20.1