Skip to content

Commit 018e8e3

Browse files
committed
ACP2E-212: Customer Grid loading on the Admin Order creation page is slow
- fix - add test
1 parent 8cdefb0 commit 018e8e3

File tree

2 files changed

+157
-14
lines changed
  • app/code/Magento/Sales/Model/ResourceModel/Order/Customer
  • dev/tests/integration/testsuite/Magento/Sales/Model/ResourceModel/Order/Customer

2 files changed

+157
-14
lines changed

app/code/Magento/Sales/Model/ResourceModel/Order/Customer/Collection.php

Lines changed: 104 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,89 @@
77
*/
88
namespace Magento\Sales\Model\ResourceModel\Order\Customer;
99

10+
use Magento\Eav\Model\Config as EavConfig;
11+
use Magento\Eav\Model\EntityFactory as EavEntityFactory;
12+
use Magento\Eav\Model\ResourceModel\Helper;
13+
use Magento\Framework\App\ResourceConnection;
14+
use Magento\Framework\Data\Collection\Db\FetchStrategyInterface;
15+
use Magento\Framework\Data\Collection\EntityFactory;
16+
use Magento\Framework\DataObject;
17+
use Magento\Framework\DataObject\Copy\Config;
18+
use Magento\Framework\DB\Adapter\AdapterInterface;
19+
use Magento\Framework\Event\ManagerInterface;
20+
use Magento\Framework\Model\ResourceModel\Db\VersionControl\Snapshot;
21+
use Magento\Framework\Validator\UniversalFactory;
22+
use Magento\Store\Model\StoreManagerInterface;
23+
use Psr\Log\LoggerInterface;
24+
25+
/**
26+
* Customer collection
27+
*
28+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
29+
*/
1030
class Collection extends \Magento\Customer\Model\ResourceModel\Customer\Collection
1131
{
1232
/**
33+
* @var StoreManagerInterface
34+
*/
35+
private $storeManager;
36+
37+
/**
38+
* Constructor
39+
*
40+
* @param EntityFactory $entityFactory
41+
* @param LoggerInterface $logger
42+
* @param FetchStrategyInterface $fetchStrategy
43+
* @param ManagerInterface $eventManager
44+
* @param EavConfig $eavConfig
45+
* @param ResourceConnection $resource
46+
* @param EavEntityFactory $eavEntityFactory
47+
* @param Helper $resourceHelper
48+
* @param UniversalFactory $universalFactory
49+
* @param Snapshot $entitySnapshot
50+
* @param Config $fieldsetConfig
51+
* @param StoreManagerInterface $storeManager
52+
* @param AdapterInterface|null $connection
53+
* @param string $modelName
54+
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
55+
*/
56+
public function __construct(
57+
EntityFactory $entityFactory,
58+
LoggerInterface $logger,
59+
FetchStrategyInterface $fetchStrategy,
60+
ManagerInterface $eventManager,
61+
EavConfig $eavConfig,
62+
ResourceConnection $resource,
63+
EavEntityFactory $eavEntityFactory,
64+
Helper $resourceHelper,
65+
UniversalFactory $universalFactory,
66+
Snapshot $entitySnapshot,
67+
Config $fieldsetConfig,
68+
StoreManagerInterface $storeManager,
69+
AdapterInterface $connection = null,
70+
$modelName = self::CUSTOMER_MODEL_NAME
71+
) {
72+
$this->storeManager = $storeManager;
73+
parent::__construct(
74+
$entityFactory,
75+
$logger,
76+
$fetchStrategy,
77+
$eventManager,
78+
$eavConfig,
79+
$resource,
80+
$eavEntityFactory,
81+
$resourceHelper,
82+
$universalFactory,
83+
$entitySnapshot,
84+
$fieldsetConfig,
85+
$connection,
86+
$modelName
87+
);
88+
}
89+
90+
/**
91+
* Init select
92+
*
1393
* @return $this
1494
*/
1595
protected function _initSelect()
@@ -49,21 +129,31 @@ protected function _initSelect()
49129
'default_billing',
50130
null,
51131
'left'
52-
)->joinField(
53-
'store_name',
54-
'store',
55-
'name',
56-
'store_id=store_id',
57-
null,
58-
'left'
59-
)->joinField(
60-
'website_name',
61-
'store_website',
62-
'name',
63-
'website_id=website_id',
64-
null,
65-
'left'
66132
);
67133
return $this;
68134
}
135+
136+
/**
137+
* Performance issue fix for large number (over million) of customers on Orders Creation page in Admin
138+
*
139+
* Initially _initSelect method of this collection had two joins to Store and Website
140+
* tables on store_id and website_id to add store and website names. This caused extreme performance drop
141+
* resulting in loading page over minute, despite all optimizations were already in place.
142+
* To fix the issue the joins were removed, instead store and website names are added in this method.
143+
*
144+
* @param DataObject $item
145+
* @return DataObject
146+
*/
147+
protected function beforeAddLoadedItem(DataObject $item): DataObject
148+
{
149+
$storeId = $item->getStoreId();
150+
$storeName = $storeId !== null ? $this->storeManager->getStore($storeId)->getName() : null;
151+
$item->setStoreName($storeName);
152+
153+
$websiteId = $item->getWebsiteId();
154+
$websiteName = $websiteId !== null ? $this->storeManager->getWebsite($websiteId)->getName() : null;
155+
$item->setWebsiteName($websiteName);
156+
157+
return parent::beforeAddLoadedItem($item);
158+
}
69159
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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\Order\Customer;
9+
10+
use Magento\Framework\ObjectManagerInterface;
11+
use Magento\Store\Api\StoreRepositoryInterface;
12+
use Magento\Store\Api\WebsiteRepositoryInterface;
13+
use Magento\TestFramework\Helper\Bootstrap;
14+
use PHPUnit\Framework\TestCase;
15+
16+
class CollectionTest extends TestCase
17+
{
18+
/**
19+
* @var ObjectManagerInterface
20+
*/
21+
private $objectManager;
22+
23+
/**
24+
* @inheritDoc
25+
*/
26+
protected function setUp(): void
27+
{
28+
$this->objectManager = Bootstrap::getObjectManager();
29+
}
30+
31+
/**
32+
* Tests that Customer collection data for Order retain website and store names after fixing performance issue.
33+
* @see \Magento\Customer\Model\ResourceModel\Customer\Collection::beforeAddLoadedItem()
34+
*
35+
* @magentoDataFixture Magento/Customer/_files/customer_for_second_website.php
36+
*/
37+
public function testCollection(): void
38+
{
39+
/** @var Collection $customerCollection */
40+
$customerCollection = $this->objectManager->create(Collection::class);
41+
$customer = $customerCollection->getItems();
42+
$customer = array_shift($customer);
43+
/** @var WebsiteRepositoryInterface $websiteRepository */
44+
$websiteRepository = $this->objectManager->get(WebsiteRepositoryInterface::class);
45+
$website = $websiteRepository->getById($customer->getWebsiteId());
46+
/** @var StoreRepositoryInterface $storeRepository */
47+
$storeRepository = $this->objectManager->get(StoreRepositoryInterface::class);
48+
$store = $storeRepository->getById($customer->getStoreId());
49+
50+
$this->assertEquals($website->getName(), $customer->getWebsiteName());
51+
$this->assertEquals($store->getName(), $customer->getStoreName());
52+
}
53+
}

0 commit comments

Comments
 (0)