Skip to content

Commit cbe8faf

Browse files
committed
ACP2E-63: Queries with bad performance
1 parent 3b3392a commit cbe8faf

File tree

2 files changed

+124
-16
lines changed

2 files changed

+124
-16
lines changed
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Sales\Model\ResourceModel\Provider\Query;
9+
10+
use Magento\Framework\App\ResourceConnection;
11+
use Magento\Framework\DB\Adapter\AdapterInterface;
12+
use Magento\Framework\DB\Select;
13+
14+
/**
15+
* Query builder for retrieving list of updated order ids that was not synced to grid table.
16+
*/
17+
class IdListBuilder
18+
{
19+
/**
20+
* @var array
21+
*/
22+
private $additionalGridTables = [];
23+
24+
/**
25+
* @var ResourceConnection
26+
*/
27+
private $resourceConnection;
28+
29+
/**
30+
* @var AdapterInterface
31+
*/
32+
private $connection;
33+
34+
/**
35+
* @param ResourceConnection $resourceConnection
36+
*/
37+
public function __construct(ResourceConnection $resourceConnection)
38+
{
39+
$this->resourceConnection = $resourceConnection;
40+
}
41+
42+
/**
43+
* @param string $table
44+
* @return $this
45+
*/
46+
public function addAdditionalGridTable(string $table): IdListBuilder
47+
{
48+
$this->additionalGridTables[] = $table;
49+
50+
return $this;
51+
}
52+
53+
/**
54+
* Returns connection.
55+
*
56+
* @return AdapterInterface
57+
*/
58+
private function getConnection(): AdapterInterface
59+
{
60+
if (!$this->connection) {
61+
$this->connection = $this->resourceConnection->getConnection('sales');
62+
}
63+
64+
return $this->connection;
65+
}
66+
67+
/**
68+
* Returns update time of the last row in the grid.
69+
*
70+
* @param string $gridTableName
71+
* @return string
72+
*/
73+
private function getLastUpdatedAtValue(string $gridTableName): string
74+
{
75+
$select = $this->getConnection()->select()
76+
->from($this->getConnection()->getTableName($gridTableName), ['updated_at'])
77+
->order('updated_at DESC')
78+
->limit(1);
79+
$row = $this->getConnection()->fetchRow($select);
80+
81+
return $row['updated_at'] ?? '0000-00-00 00:00:00';
82+
}
83+
84+
/**
85+
* @return Select
86+
*/
87+
public function build($mainTableName, $gridTableName): Select
88+
{
89+
$select = $this->getConnection()->select()
90+
->from($mainTableName, [$mainTableName . '.entity_id']);
91+
$lastUpdateTime = $this->getLastUpdatedAtValue($gridTableName);
92+
$select->where($mainTableName . '.updated_at >= ?', $lastUpdateTime);
93+
foreach ($this->additionalGridTables as $table) {
94+
$select->joinLeft(
95+
[$table => $table],
96+
sprintf(
97+
'%s.%s = %s.%s',
98+
$mainTableName,
99+
'entity_id',
100+
$table,
101+
'entity_id'
102+
),
103+
[]
104+
)
105+
->where($table . '.entity_id IS NULL');
106+
}
107+
return $select;
108+
}
109+
}

app/code/Magento/Sales/Model/ResourceModel/Provider/UpdatedIdListProvider.php

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
*/
66
namespace Magento\Sales\Model\ResourceModel\Provider;
77

8+
use Magento\Framework\App\ObjectManager;
89
use Magento\Framework\App\ResourceConnection;
910
use Magento\Framework\DB\Adapter\AdapterInterface;
11+
use Magento\Sales\Model\ResourceModel\Provider\Query\IdListBuilder;
1012

1113
/**
1214
* Provides latest updated entities ids list
@@ -23,14 +25,25 @@ class UpdatedIdListProvider implements NotSyncedDataProviderInterface
2325
*/
2426
private $connection;
2527

28+
/**
29+
* @var IdListBuilder
30+
*/
31+
private $idListQueryBuilder;
32+
2633
/**
2734
* NotSyncedDataProvider constructor.
2835
* @param ResourceConnection $resourceConnection
36+
* @param IdListBuilder|null $idListQueryBuilder
2937
*/
3038
public function __construct(
31-
ResourceConnection $resourceConnection
39+
ResourceConnection $resourceConnection,
40+
IdListBuilder $idListQueryBuilder = null
3241
) {
3342
$this->resourceConnection = $resourceConnection;
43+
if (!$idListQueryBuilder) {
44+
$idListQueryBuilder = ObjectManager::getInstance()->get(IdListBuilder::class);
45+
}
46+
$this->idListQueryBuilder = $idListQueryBuilder;
3447
}
3548

3649
/**
@@ -40,21 +53,7 @@ public function getIds($mainTableName, $gridTableName)
4053
{
4154
$mainTableName = $this->resourceConnection->getTableName($mainTableName);
4255
$gridTableName = $this->resourceConnection->getTableName($gridTableName);
43-
$select = $this->getConnection()->select()
44-
->from($mainTableName, [$mainTableName . '.entity_id'])
45-
->joinLeft(
46-
[$gridTableName => $gridTableName],
47-
sprintf(
48-
'%s.%s = %s.%s',
49-
$mainTableName,
50-
'entity_id',
51-
$gridTableName,
52-
'entity_id'
53-
),
54-
[]
55-
)
56-
->where($gridTableName . '.entity_id IS NULL');
57-
56+
$select = $this->idListQueryBuilder->build($mainTableName, $gridTableName);
5857
return $this->getConnection()->fetchAll($select, [], \Zend_Db::FETCH_COLUMN);
5958
}
6059

0 commit comments

Comments
 (0)