Open
Description
Preconditions (*)
- Magento 2.3.3
Steps to reproduce (*)
- Install Magento
- Copy
setup/performance-toolkit/profiles/ce/small.xml
to a new file - Update the file to have 2000 simple products and 2000 categories
- Generate fixtures using the file
- Run the Catalog Rule Product index
php bin/magento indexer:reindex catalogrule_rule
- Repeat steps 1 - 5 increasing the number of rules from 20 to 100, 500, 1,000, 5,000, 10,000, and 25,000
Expected result (*)
- The index time should increase in a roughly linear manner as the number of rules increases
Actual result (*)
- The index takes longer and longer to complete as the number of rules increase
# With 20 catalog price rules
$ php bin/magento indexer:reindex catalogrule_rule
Catalog Rule Product index has been rebuilt successfully in 00:00:01
Product Price index has been rebuilt successfully in 00:00:02
Catalog Search index has been rebuilt successfully in 00:00:11
# With 100 catalog price rules
$ php bin/magento indexer:reindex catalogrule_rule
Catalog Rule Product index has been rebuilt successfully in 00:00:02
Product Price index has been rebuilt successfully in 00:00:01
Catalog Search index has been rebuilt successfully in 00:00:12
# With 500 catalog price rules
$ php bin/magento indexer:reindex catalogrule_rule
Catalog Rule Product index has been rebuilt successfully in 00:00:13
Product Price index has been rebuilt successfully in 00:00:02
Catalog Search index has been rebuilt successfully in 00:00:11
# With 1,000 catalog price rules
$ php bin/magento indexer:reindex catalogrule_rule
Catalog Rule Product index has been rebuilt successfully in 00:00:28
Product Price index has been rebuilt successfully in 00:00:02
Catalog Search index has been rebuilt successfully in 00:00:11
# With 5,000 catalog price rules
$ php bin/magento indexer:reindex catalogrule_rule
Catalog Rule Product index has been rebuilt successfully in 00:03:11
Product Price index has been rebuilt successfully in 00:00:02
Catalog Search index has been rebuilt successfully in 00:00:11
# With 10,000 catalog price rules
$php bin/magento indexer:reindex catalogrule_rule
Catalog Rule Product index has been rebuilt successfully in 00:11:19
Product Price index has been rebuilt successfully in 00:00:02
Catalog Search index has been rebuilt successfully in 00:00:11
# With 25,000 catalog price rules
$php bin/magento indexer:reindex catalogrule_rule
Catalog Rule Product index has been rebuilt successfully in 01:06:46
Product Price index has been rebuilt successfully in 00:00:02
Catalog Search index has been rebuilt successfully in 00:00:12
Explanation
The rules are generated using the \Magento\CatalogRule\Model\Indexer\IndexBuilder::doReindexFull function which fetches a RuleCollection
and then calls foreach
on it.
This triggers the getIterator
method on the Collection which loads everything before passing the collection to an ArrayIterator
. As the size of the collection increases this step takes more and more time before any of the processing can be started
Proposed Solution
Replacing the foreach
loop with a while loop like so
protected function doReindexFull()
{
$collection = $this->getAllRules();
while ($rule = $collection->fetchItem()) {
$this->reindexRuleProduct->execute($rule, $this->batchCount, true);
}
/* Rest of function unchanged */
}
This means that each rule gets loaded individually, which cuts the time needed to index significantly when there are a large number of rules, without impacting the time when there are a small number.
Re-indexing times with the change in place
# With 20 catalog price rules
$ php bin/magento indexer:reindex catalogrule_rule
Catalog Rule Product index has been rebuilt successfully in 00:00:01
Product Price index has been rebuilt successfully in 00:00:02
Catalog Search index has been rebuilt successfully in 00:00:11
# With 5,000 catalog price rules
$ php bin/magento indexer:reindex catalogrule_rule
Catalog Rule Product index has been rebuilt successfully in 00:00:23
Product Price index has been rebuilt successfully in 00:00:02
Catalog Search index has been rebuilt successfully in 00:00:11
# With 25,000 catalog price rules
$ php bin/magento indexer:reindex catalogrule_rule
Catalog Rule Product index has been rebuilt successfully in 00:03:58
Product Price index has been rebuilt successfully in 00:00:02
Catalog Search index has been rebuilt successfully in 00:00:12
Metadata
Assignees
Labels
Issue recommended for the contribution dayGate 3 Passed. Manual verification of the issue completed. Issue is confirmedGate 1 Passed. Automatic verification of issue format passedGate 4. Acknowledged. Issue is added to backlog and ready for developmentA defect with this priority could have functionality issues which are not to expectations.The issue has been reproduced on latest 2.3 releaseAffects critical data or functionality and forces users to employ a workaround.Issue related to Developer Experience and needs help with Triage to Confirm or Reject it