From b66bb911b57fbbd39df97fc1878aaa46dea7590f Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Fri, 6 Jun 2014 11:54:50 -0700 Subject: [PATCH] More optimizations to User::saveOptions() * Avoid doing the DELETE for unchanged rows. This method is often called when one new preference (e.g. watchlist token) is set. These cases will now simple result in an INSERT, even if the user already has some preferences set. bug: 36116 Change-Id: Ib7c558e7c06927875086b86ea719ac1323a7b4a8 --- includes/User.php | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/includes/User.php b/includes/User.php index b5fb1ff7c0..f2d3d9b18d 100644 --- a/includes/User.php +++ b/includes/User.php @@ -4795,13 +4795,13 @@ class User { } $userId = $this->getId(); - $insert_rows = array(); + + $insert_rows = array(); // all the new preference rows foreach ( $saveOptions as $key => $value ) { // Don't bother storing default values $defaultOption = self::getDefaultOption( $key ); - if ( ( is_null( $defaultOption ) && - !( $value === false || is_null( $value ) ) ) || - $value != $defaultOption + if ( ( $defaultOption === null && $value !== false && $value !== null ) + || $value != $defaultOption ) { $insert_rows[] = array( 'up_user' => $userId, @@ -4812,14 +4812,22 @@ class User { } $dbw = wfGetDB( DB_MASTER ); - // Find and delete any prior preference rows... + $res = $dbw->select( 'user_properties', - array( 'up_property' ), array( 'up_user' => $userId ), __METHOD__ ); - $priorKeys = array(); + array( 'up_property', 'up_value' ), array( 'up_user' => $userId ), __METHOD__ ); + + // Find prior rows that need to be removed or updated. These rows will + // all be deleted (the later so that INSERT IGNORE applies the new values). + $keysDelete = array(); foreach ( $res as $row ) { - $priorKeys[] = $row->up_property; + if ( !isset( $saveOptions[$row->up_property] ) + || strcmp( $saveOptions[$row->up_property], $row->up_value ) != 0 + ) { + $keysDelete[] = $row->up_property; + } } - if ( count( $priorKeys ) ) { + + if ( count( $keysDelete ) ) { // Do the DELETE by PRIMARY KEY for prior rows. // In the past a very large portion of calls to this function are for setting // 'rememberpassword' for new accounts (a preference that has since been removed). @@ -4828,7 +4836,7 @@ class User { // updates would pile up on each other as they are for higher (newer) user IDs. // It might not be necessary these days, but it shouldn't hurt either. $dbw->delete( 'user_properties', - array( 'up_user' => $userId, 'up_property' => $priorKeys ), __METHOD__ ); + array( 'up_user' => $userId, 'up_property' => $keysDelete ), __METHOD__ ); } // Insert the new preference rows $dbw->insert( 'user_properties', $insert_rows, __METHOD__, array( 'IGNORE' ) ); -- 2.20.1