diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -4088,6 +4088,7 @@ 'PhabricatorStorageFixtureScopeGuard' => 'infrastructure/testing/fixture/PhabricatorStorageFixtureScopeGuard.php', 'PhabricatorStorageManagementAPI' => 'infrastructure/storage/management/PhabricatorStorageManagementAPI.php', 'PhabricatorStorageManagementAdjustWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementAdjustWorkflow.php', + 'PhabricatorStorageManagementAnalyzeWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementAnalyzeWorkflow.php', 'PhabricatorStorageManagementDatabasesWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDatabasesWorkflow.php', 'PhabricatorStorageManagementDestroyWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDestroyWorkflow.php', 'PhabricatorStorageManagementDumpWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDumpWorkflow.php', @@ -9679,6 +9680,7 @@ 'PhabricatorStorageFixtureScopeGuard' => 'Phobject', 'PhabricatorStorageManagementAPI' => 'Phobject', 'PhabricatorStorageManagementAdjustWorkflow' => 'PhabricatorStorageManagementWorkflow', + 'PhabricatorStorageManagementAnalyzeWorkflow' => 'PhabricatorStorageManagementWorkflow', 'PhabricatorStorageManagementDatabasesWorkflow' => 'PhabricatorStorageManagementWorkflow', 'PhabricatorStorageManagementDestroyWorkflow' => 'PhabricatorStorageManagementWorkflow', 'PhabricatorStorageManagementDumpWorkflow' => 'PhabricatorStorageManagementWorkflow', diff --git a/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementAnalyzeWorkflow.php b/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementAnalyzeWorkflow.php new file mode 100644 --- /dev/null +++ b/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementAnalyzeWorkflow.php @@ -0,0 +1,19 @@ +setName('analyze') + ->setExamples('**analyze**') + ->setSynopsis( + pht('Run "ANALYZE TABLE" on tables to improve performance.')); + } + + public function didExecute(PhutilArgumentParser $args) { + $this->analyzeTables(); + return 0; + } + +} diff --git a/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementWorkflow.php b/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementWorkflow.php --- a/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementWorkflow.php +++ b/src/infrastructure/storage/management/workflow/PhabricatorStorageManagementWorkflow.php @@ -137,6 +137,15 @@ try { $err = $this->doAdjustSchemata($api, $unsafe); + + // Analyze tables if we're not doing a dry run and adjustments are either + // all clear or have minor errors like surplus tables. + if (!$this->dryRun) { + $should_analyze = (($err == 0) || ($err == 2)); + if ($should_analyze) { + $this->analyzeTables(); + } + } } catch (Exception $ex) { $lock->unlock(); throw $ex; @@ -1163,4 +1172,53 @@ ->lock(); } + final protected function analyzeTables() { + // Analyzing tables can sometimes have a significant effect on query + // performance, particularly for the fulltext ngrams tables. See T12819 + // for some specific examples. + + $api = $this->getSingleAPI(); + $conn = $api->getConn(null); + + $patches = $this->getPatches(); + $databases = $api->getDatabaseList($patches, true); + + $this->logInfo( + pht('ANALYZE'), + pht('Analyzing tables...')); + + $targets = array(); + foreach ($databases as $database) { + queryfx($conn, 'USE %C', $database); + $tables = queryfx_all($conn, 'SHOW TABLE STATUS'); + foreach ($tables as $table) { + $table_name = $table['Name']; + + $targets[] = array( + 'database' => $database, + 'table' => $table_name, + ); + } + } + + $bar = id(new PhutilConsoleProgressBar()) + ->setTotal(count($targets)); + foreach ($targets as $target) { + queryfx( + $conn, + 'ANALYZE TABLE %T.%T', + $target['database'], + $target['table']); + + $bar->update(1); + } + $bar->done(); + + $this->logOkay( + pht('ANALYZED'), + pht( + 'Analyzed %d table(s).', + count($targets))); + } + }