Skip to content

Commit e86d8d6

Browse files
committed
Fix the performance of some migrations
1 parent 6e33ff5 commit e86d8d6

3 files changed

Lines changed: 43 additions & 73 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Unreleased
44

55
- Fixed a PHP error that occurred when marking an inventory transfer as pending. ([#4267](https://github.com/craftcms/commerce/issues/4267))
6+
- Improved the performance of migrations when upgrading to 5.x. ([#4277](https://github.com/craftcms/commerce/issues/4277))
67

78
## 5.6.1.1 - 2026-03-27
89

src/migrations/m220912_111800_add_order_total_qty_column.php

Lines changed: 21 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
namespace craft\commerce\migrations;
44

55
use craft\db\Migration;
6-
use craft\db\Query;
7-
use yii\db\Expression;
86

97
/**
108
* m220912_111800_add_order_total_qty_column migration.
@@ -19,41 +17,28 @@ public function safeUp(): bool
1917
if (!$this->db->columnExists('{{%commerce_orders}}', 'totalQty')) {
2018
$this->addColumn('{{%commerce_orders}}', 'totalQty', $this->integer()->unsigned());
2119

22-
$sums = (new Query())
23-
->select([new Expression('SUM(qty) as [[totalQty]]'), '[[orderId]]'])
24-
->from('{{%commerce_lineitems}}')
25-
->indexBy('orderId')
26-
->groupBy('[[orderId]]')
27-
->all();
28-
29-
$idsByQty = [];
30-
foreach ($sums as $sum) {
31-
if (!isset($idsByQty[$sum['totalQty']])) {
32-
$idsByQty[$sum['totalQty']] = [];
33-
}
34-
35-
$idsByQty[$sum['totalQty']][] = $sum['orderId'];
36-
}
37-
38-
$cases = [];
39-
foreach ($idsByQty as $totalQty => $ids) {
40-
$cases[] = 'WHEN id IN (' . implode(', ', $ids) . ') THEN ' . $totalQty;
20+
if ($this->db->getIsMysql()) {
21+
$this->execute('
22+
UPDATE {{%commerce_orders}} o
23+
LEFT JOIN (
24+
SELECT [[orderId]], SUM([[qty]]) AS [[totalQty]]
25+
FROM {{%commerce_lineitems}}
26+
GROUP BY [[orderId]]
27+
) agg ON agg.[[orderId]] = o.[[id]]
28+
SET o.[[totalQty]] = COALESCE(agg.[[totalQty]], 0)
29+
');
30+
} else {
31+
$this->execute('
32+
UPDATE {{%commerce_orders}} o
33+
SET [[totalQty]] = COALESCE(agg.[[totalQty]], 0)
34+
FROM (
35+
SELECT [[orderId]], SUM([[qty]]) AS [[totalQty]]
36+
FROM {{%commerce_lineitems}}
37+
GROUP BY [[orderId]]
38+
) agg
39+
WHERE o.[[id]] = agg.[[orderId]]
40+
');
4141
}
42-
43-
if (!empty($cases)) {
44-
$batches = array_chunk($cases, 5);
45-
foreach ($batches as $batch) {
46-
$this->update(
47-
'{{%commerce_orders}}',
48-
['totalQty' => new Expression(sprintf('(CASE %s END)', implode(' ', $batch)))],
49-
[],
50-
[],
51-
false,
52-
);
53-
}
54-
}
55-
56-
$this->update('{{%commerce_orders}}', ['totalQty' => 0], ['totalQty' => null], [], false);
5742
}
5843

5944
return true;

src/migrations/m230214_094122_add_total_weight_column_to_orders.php

Lines changed: 21 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
use craft\commerce\db\Table;
66
use craft\db\Migration;
7-
use craft\db\Query;
8-
use yii\db\Expression;
97

108
/**
119
* m230214_094122_add_total_weight_column_to_orders migration.
@@ -19,43 +17,29 @@ public function safeUp(): bool
1917
{
2018
$this->addColumn(Table::ORDERS, 'totalWeight', $this->decimal(14, 4)->defaultValue(0)->unsigned());
2119

22-
$sums = (new Query())
23-
->select([new Expression('SUM(weight) as [[totalWeight]]'), '[[orderId]]'])
24-
->from(Table::LINEITEMS)
25-
->indexBy('orderId')
26-
->groupBy('[[orderId]]')
27-
->all();
28-
29-
$idsByWeight = [];
30-
foreach ($sums as $sum) {
31-
if (!isset($idsByWeight[$sum['totalWeight']])) {
32-
$idsByWeight[$sum['totalWeight']] = [];
33-
}
34-
35-
$idsByWeight[$sum['totalWeight']][] = $sum['orderId'];
36-
}
37-
38-
$cases = [];
39-
foreach ($idsByWeight as $totalWeight => $ids) {
40-
$cases[] = 'WHEN id IN (' . implode(', ', $ids) . ') THEN ' . $totalWeight;
20+
if ($this->db->getIsMysql()) {
21+
$this->execute('
22+
UPDATE ' . Table::ORDERS . ' o
23+
LEFT JOIN (
24+
SELECT [[orderId]], SUM([[weight]]) AS [[totalWeight]]
25+
FROM ' . Table::LINEITEMS . '
26+
GROUP BY [[orderId]]
27+
) agg ON agg.[[orderId]] = o.[[id]]
28+
SET o.[[totalWeight]] = COALESCE(agg.[[totalWeight]], 0)
29+
');
30+
} else {
31+
$this->execute('
32+
UPDATE ' . Table::ORDERS . ' o
33+
SET [[totalWeight]] = COALESCE(agg.[[totalWeight]], 0)
34+
FROM (
35+
SELECT [[orderId]], SUM([[weight]]) AS [[totalWeight]]
36+
FROM ' . Table::LINEITEMS . '
37+
GROUP BY [[orderId]]
38+
) agg
39+
WHERE o.[[id]] = agg.[[orderId]]
40+
');
4141
}
4242

43-
if (!empty($cases)) {
44-
$batches = array_chunk($cases, 5);
45-
foreach ($batches as $batch) {
46-
$this->update(
47-
Table::ORDERS,
48-
['totalWeight' => new Expression(sprintf('(CASE %s END)', implode(' ', $batch)))],
49-
[],
50-
[],
51-
false,
52-
);
53-
}
54-
}
55-
56-
$this->update(Table::ORDERS, ['totalWeight' => 0], ['totalWeight' => null], [], false);
57-
58-
5943
return true;
6044
}
6145

0 commit comments

Comments
 (0)