/ #magento 

Проблема переіндексації великого каталогу в Magento 2

Вихідні данні: Magento 2.3.1, каталог - 300K Проблема: переіндексація каталогу може відбуватись більше 24 годин (може й більше, ніхто не перевіряв)

Пошуки рішення привели до такого твіту:

а також до такого issue https://github.com/magento/magento2/issues/10531 .

Хоча обговоренню більше 2 років, здається воно актуальне і для 2.3.1.

Мені допомогли ці дві штуки:

  1. задати великий batchRowsCount в di.xml

    <type name="Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\BatchSizeCalculator">
        <arguments>
            <argument name="batchRowsCount" xsi:type="array">
                <item name="default" xsi:type="number">500000</item>
            </argument>
        </arguments>
    </type>
    
  2. збільшити $batchSize в /vendor/magento/module-catalog-inventory/Model/Indexer/ProductPriceIndexFilter.php (67)

        public function __construct(
            StockConfigurationInterface $stockConfiguration,
            Item $stockItem,
            ResourceConnection $resourceConnection = null,
            $connectionName = 'indexer',
            Generator $batchQueryGenerator = null,
            $batchSize = 20000
        ) {
            $this->stockConfiguration = $stockConfiguration;
            $this->stockItem = $stockItem;
            $this->resourceConnection = $resourceConnection ?: ObjectManager::getInstance()->get(ResourceConnection::class);
            $this->connectionName = $connectionName;
            $this->batchQueryGenerator = $batchQueryGenerator ?: ObjectManager::getInstance()->get(Generator::class);
            $this->batchSize = $batchSize;
        }
    
    

P.S. Ейфорія тривала не довго, аж до наступної переіндексації. Розслідування продовжилось і виплив ось такий issue - https://github.com/magento/magento2/issues/23077, який пов’язаний з неправильною роботою тригерів і створенням дублів товарів для індексації. Ну і власне виправлення - https://github.com/sebastien-kathmandu/magento2/pull/1/commits/444bc8d2805ab0c57a66e656332394f0123c63df.

Раніше у vendor/magento/framework/Mview/View/Subscription.php (принаймі у версії 2.2.5) було так:

foreach ($columnNames as $columnName) {
    $columns[] = sprintf(
        'NEW.%1$s != OLD.%1$s',
        $this->connection->quoteIdentifier($columnName)
    );
}  

потім стало так:

foreach ($columnNames as $columnName) {
    $columns[] = sprintf(
        'NEW.%1$s <=> OLD.%1$s',
        $this->connection->quoteIdentifier($columnName)
    );
} 

Фактично, від перевірки на нерівність двох змінних, перейшли до перевірки на рівність, що очевидно є помилкою, бо спричиняє лавиноподібне заповнення таблиць з префіксом cl. В якості виправлення запропоновано такий варіант:

foreach ($columnNames as $columnName) {
    $columns[] = sprintf(
        'NOT NEW.%1$s <=> OLD.%1$s',
        $this->connection->quoteIdentifier($columnName)
    );
} 

Посилання

Author

Олександр Бобилєв

Залишаю собі право використовувати ненормативну (але інформативну) лексику там, де звичайні слова втрачають сенс і не відображають всієї палітри почуттів, від споглядання навколишньої дійсності.