Skip to content

Commit

Permalink
Drop non unique indexes on data loading
Browse files Browse the repository at this point in the history
  • Loading branch information
Ioannis committed Feb 27, 2026
1 parent 87fdd75 commit 259089b
Show file tree
Hide file tree
Showing 3 changed files with 389 additions and 2 deletions.
58 changes: 57 additions & 1 deletion app/plugins/Transmogrify/src/Command/TransmogrifyCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
use Transmogrify\Lib\Util\CommandLinePrinter;
use Transmogrify\Lib\Util\DbInfoPrinter;
use Transmogrify\Lib\Util\GroupsHealth;
use Transmogrify\Lib\Util\IndexManager;
use Transmogrify\Lib\Util\OrgIdentitiesHealth;
use Transmogrify\Lib\Util\RawSqlQueries;
use Transmogrify\Service\ConfigLoaderService;
Expand Down Expand Up @@ -86,6 +87,9 @@ class TransmogrifyCommand extends BaseCommand {

protected ?CommandLinePrinter $cmdPrinter = null;

/** @var float Start time of command execution */
private float $startTime;

/** @var string Absolute path to plugin root directory */
private string $pluginRoot;

Expand All @@ -98,6 +102,7 @@ class TransmogrifyCommand extends BaseCommand {
public function __construct(
private DbInfoService $dbInfoService,
private ConfigLoaderService $configLoader,
private IndexManager $indexManager,
) {
$this->pluginRoot = dirname(__DIR__, 2);
parent::__construct();
Expand Down Expand Up @@ -219,9 +224,15 @@ public function execute(Arguments $args, ConsoleIo $io): int
$this->args = $args;
$this->io = $io;

// Now that BaseCommand set verbosity, construct the printer so it can detect it correctly
// Now that BaseCommand set verbosity, construct the printer so it can detect it correctly
$this->cmdPrinter = new CommandLinePrinter($io, 'green', 50, true);

// Start tracking execution time
$this->startTime = microtime(true);

// Initialize the index manager with the live target connection and printer
$this->indexManager->initialize($this->outconn, $this->cmdPrinter);

// Validate "info" option combinations and handle errors
$code = $this->validateInfoOptions($io);
if ($code !== null) {
Expand Down Expand Up @@ -408,6 +419,21 @@ public function execute(Arguments $args, ConsoleIo $io): int
$this->cache['error'] = 0;
$this->cache['warns'] = 0;

// Drop non-PK indexes before the bulk load to avoid per-row index maintenance overhead.
// They will be recreated in a single pass after all rows are inserted.
$indexesDisabled = false;
if ($this->cache['skipInsert'][$outboundQualifiedTableName] === false) {
try {
$this->indexManager->disableIndexes($outboundQualifiedTableName);
$indexesDisabled = $this->indexManager->hasSavedIndexes($outboundQualifiedTableName);
} catch (\Throwable $e) {
$this->cmdPrinter->warning(
'Could not drop indexes on ' . $outboundQualifiedTableName . ': ' . $e->getMessage()
);
$this->cmdPrinter->warning('Proceeding with indexes in place (slower).');
}
}

while ($row = $stmt->fetchAssociative()) {
if (!empty($row[$this->tables[$t]['displayField']])) {
$displayMessage = "$t " . $row[$this->tables[$t]['displayField']];
Expand Down Expand Up @@ -492,6 +518,20 @@ public function execute(Arguments $args, ConsoleIo $io): int
* FINISH PROGRESS
*/

// Recreate indexes that were dropped before the bulk load
if ($indexesDisabled) {
try {
$this->indexManager->enableIndexes($outboundQualifiedTableName);
} catch (\Throwable $e) {
$this->cmdPrinter->error(
'Failed to recreate indexes on ' . $outboundQualifiedTableName . ': ' . $e->getMessage()
);
$this->cmdPrinter->error(
'You may need to manually recreate indexes. Run: bin/cake database'
);
}
}

// Output final warning and error counts for the table
$this->cmdPrinter->warning(sprintf('Warnings: %d', $this->cache['warns']));
$this->cmdPrinter->error(sprintf('Errors: %d', $this->cache['error']));
Expand Down Expand Up @@ -527,6 +567,22 @@ public function execute(Arguments $args, ConsoleIo $io): int
$this->cmdPrinter->out('Running assignUuids task via UpgradeCommand...');
$this->executeCommand(UpgradeCommand::class, ['-D', '-X', '-t', 'assignUuids'], $this->io);

// Display total execution time
$executionTime = microtime(true) - $this->startTime;

$hours = floor($executionTime / 3600);
$minutes = floor(($executionTime % 3600) / 60);
$seconds = $executionTime % 60;

$formatted = sprintf(
'%02d:%02d:%02d',
(int)$hours,
(int)$minutes,
(int)$seconds
);

$this->cmdPrinter->out(sprintf('Total execution time: %s (HH:MM:SS)', $formatted));

return BaseCommand::CODE_SUCCESS;
}

Expand Down
Loading

0 comments on commit 259089b

Please sign in to comment.