Skip to content

Catalog Rule Product index time increases exponentially as new rules are added #25889

Open
@rossmitchell

Description

Preconditions (*)

  1. Magento 2.3.3

Steps to reproduce (*)

  1. Install Magento
  2. Copy setup/performance-toolkit/profiles/ce/small.xml to a new file
  3. Update the file to have 2000 simple products and 2000 categories
  4. Generate fixtures using the file
  5. Run the Catalog Rule Product index php bin/magento indexer:reindex catalogrule_rule
  6. 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 (*)

  1. The index time should increase in a roughly linear manner as the number of rules increases

Actual result (*)

  1. 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

No one assigned

    Labels

    Area: CatalogArea: PerformanceCDIssue recommended for the contribution dayComponent: IndexerIssue: ConfirmedGate 3 Passed. Manual verification of the issue completed. Issue is confirmedIssue: Format is validGate 1 Passed. Automatic verification of issue format passedIssue: Ready for WorkGate 4. Acknowledged. Issue is added to backlog and ready for developmentPriority: P2A defect with this priority could have functionality issues which are not to expectations.Progress: ready for devReproduced on 2.3.xThe issue has been reproduced on latest 2.3 releaseSeverity: S1Affects critical data or functionality and forces users to employ a workaround.Triage: Dev.ExperienceIssue related to Developer Experience and needs help with Triage to Confirm or Reject it

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions