/ #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

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

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