Skip to content

Commit 50356a8

Browse files
author
Volodymyr Klymenko
authored
Merge pull request #946 from magento-east/MAGETWO-66401
[EAST-2.1] MAGETWO-66401: [Backport] - [Performance] Bump in stock SQL queries - for 2.1.6
2 parents 24024fb + e1e911f commit 50356a8

File tree

2 files changed

+37
-24
lines changed

2 files changed

+37
-24
lines changed

app/code/Magento/ConfigurableProduct/Pricing/Price/LowestPriceOptionsProvider.php

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ class LowestPriceOptionsProvider implements LowestPriceOptionsProviderInterface
3030
*/
3131
private $collectionFactory;
3232

33+
/**
34+
* Key is product id. Value is prepared product collection
35+
*
36+
* @var array
37+
*/
38+
private $productsMap;
39+
3340
/**
3441
* @param ResourceConnection $resourceConnection
3542
* @param LinkedProductSelectBuilderInterface $linkedProductSelectBuilder
@@ -50,14 +57,16 @@ public function __construct(
5057
*/
5158
public function getProducts(ProductInterface $product)
5259
{
53-
$productIds = $this->resource->getConnection()->fetchCol(
54-
'(' . implode(') UNION (', $this->linkedProductSelectBuilder->build($product->getId())) . ')'
55-
);
56-
57-
$lowestPriceChildProducts = $this->collectionFactory->create()
58-
->addAttributeToSelect(['price', 'special_price'])
59-
->addIdFilter($productIds)
60-
->getItems();
61-
return $lowestPriceChildProducts;
60+
if (!isset($this->productsMap[$product->getId()])) {
61+
$productIds = $this->resource->getConnection()->fetchCol(
62+
'(' . implode(') UNION (', $this->linkedProductSelectBuilder->build($product->getId())) . ')'
63+
);
64+
65+
$this->productsMap[$product->getId()] = $this->collectionFactory->create()
66+
->addAttributeToSelect(['price', 'special_price'])
67+
->addIdFilter($productIds)
68+
->getItems();
69+
}
70+
return $this->productsMap[$product->getId()];
6271
}
6372
}

dev/tests/integration/testsuite/Magento/ConfigurableProduct/Pricing/Price/LowestPriceOptionProviderTest.php

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,6 @@ class LowestPriceOptionProviderTest extends \PHPUnit_Framework_TestCase
1818
*/
1919
private $storeManager;
2020

21-
/**
22-
* @var LowestPriceOptionsProviderInterface
23-
*/
24-
private $lowestPriceOptionsProvider;
25-
2621
/**
2722
* @var ProductRepositoryInterface
2823
*/
@@ -32,9 +27,6 @@ protected function setUp()
3227
{
3328
$this->storeManager = Bootstrap::getObjectManager()->get(StoreManagerInterface::class);
3429
$this->productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class);
35-
$this->lowestPriceOptionsProvider = Bootstrap::getObjectManager()->get(
36-
LowestPriceOptionsProviderInterface::class
37-
);
3830
}
3931

4032
/**
@@ -43,7 +35,7 @@ protected function setUp()
4335
public function testGetProductsIfOneOfChildIsDisabled()
4436
{
4537
$configurableProduct = $this->productRepository->get('configurable', false, null, true);
46-
$lowestPriceChildrenProducts = $this->lowestPriceOptionsProvider->getProducts($configurableProduct);
38+
$lowestPriceChildrenProducts = $this->createLowestPriceOptionsProvider()->getProducts($configurableProduct);
4739
$this->assertCount(1, $lowestPriceChildrenProducts);
4840
$lowestPriceChildrenProduct = reset($lowestPriceChildrenProducts);
4941
$this->assertEquals(10, $lowestPriceChildrenProduct->getPrice());
@@ -62,7 +54,8 @@ public function testGetProductsIfOneOfChildIsDisabled()
6254
$this->productRepository->save($lowestPriceChildProduct);
6355
$this->storeManager->setCurrentStore($currentStoreId);
6456

65-
$lowestPriceChildrenProducts = $this->lowestPriceOptionsProvider->getProducts($configurableProduct);
57+
$lowestPriceChildrenProducts = $this->createLowestPriceOptionsProvider()->getProducts($configurableProduct);
58+
6659
$this->assertCount(1, $lowestPriceChildrenProducts);
6760
$lowestPriceChildrenProduct = reset($lowestPriceChildrenProducts);
6861
$this->assertEquals(20, $lowestPriceChildrenProduct->getPrice());
@@ -74,7 +67,7 @@ public function testGetProductsIfOneOfChildIsDisabled()
7467
public function testGetProductsIfOneOfChildIsDisabledPerStore()
7568
{
7669
$configurableProduct = $this->productRepository->get('configurable', false, null, true);
77-
$lowestPriceChildrenProducts = $this->lowestPriceOptionsProvider->getProducts($configurableProduct);
70+
$lowestPriceChildrenProducts = $this->createLowestPriceOptionsProvider()->getProducts($configurableProduct);
7871
$this->assertCount(1, $lowestPriceChildrenProducts);
7972
$lowestPriceChildrenProduct = reset($lowestPriceChildrenProducts);
8073
$this->assertEquals(10, $lowestPriceChildrenProduct->getPrice());
@@ -94,7 +87,7 @@ public function testGetProductsIfOneOfChildIsDisabledPerStore()
9487
$this->productRepository->save($lowestPriceChildProduct);
9588
$this->storeManager->setCurrentStore($currentStoreId);
9689

97-
$lowestPriceChildrenProducts = $this->lowestPriceOptionsProvider->getProducts($configurableProduct);
90+
$lowestPriceChildrenProducts = $this->createLowestPriceOptionsProvider()->getProducts($configurableProduct);
9891
$this->assertCount(1, $lowestPriceChildrenProducts);
9992
$lowestPriceChildrenProduct = reset($lowestPriceChildrenProducts);
10093
$this->assertEquals(20, $lowestPriceChildrenProduct->getPrice());
@@ -106,7 +99,7 @@ public function testGetProductsIfOneOfChildIsDisabledPerStore()
10699
public function testGetProductsIfOneOfChildIsOutOfStock()
107100
{
108101
$configurableProduct = $this->productRepository->get('configurable', false, null, true);
109-
$lowestPriceChildrenProducts = $this->lowestPriceOptionsProvider->getProducts($configurableProduct);
102+
$lowestPriceChildrenProducts = $this->createLowestPriceOptionsProvider()->getProducts($configurableProduct);
110103
$this->assertCount(1, $lowestPriceChildrenProducts);
111104
$lowestPriceChildrenProduct = reset($lowestPriceChildrenProducts);
112105
$this->assertEquals(10, $lowestPriceChildrenProduct->getPrice());
@@ -121,10 +114,21 @@ public function testGetProductsIfOneOfChildIsOutOfStock()
121114
$stockItem = $lowestPriceChildProduct->getExtensionAttributes()->getStockItem();
122115
$stockItem->setIsInStock(0);
123116
$this->productRepository->save($lowestPriceChildProduct);
124-
125-
$lowestPriceChildrenProducts = $this->lowestPriceOptionsProvider->getProducts($configurableProduct);
117+
$lowestPriceChildrenProducts = $this->createLowestPriceOptionsProvider()->getProducts($configurableProduct);
126118
$this->assertCount(1, $lowestPriceChildrenProducts);
127119
$lowestPriceChildrenProduct = reset($lowestPriceChildrenProducts);
128120
$this->assertEquals(20, $lowestPriceChildrenProduct->getPrice());
129121
}
122+
123+
/**
124+
* As LowestPriceOptionsProviderInterface used multiple times in scope
125+
* of one test we need to always recreate it and prevent internal caching in property
126+
* @return LowestPriceOptionsProviderInterface
127+
*/
128+
private function createLowestPriceOptionsProvider()
129+
{
130+
return Bootstrap::getObjectManager()->create(
131+
LowestPriceOptionsProviderInterface::class
132+
);
133+
}
130134
}

0 commit comments

Comments
 (0)