В офіційній документації:
https://devdocs.magento.com/guides/v2.3/extension-dev-guide/indexing.html
є елемент:
`Allows tracking database changes for a certain entity (product, category and so on) and running change handler.
Emulates the materialized view technology for MySQL using triggers and separate materialization process (provides executing PHP code instead of SQL queries, which allows materializing multiple queries).`
MView означає Матеріалізований вигляд, який є знімком бази даних у певний момент часу.
https://en.wikipedia.org/wiki/Materialized_view
Чому нам потрібно дублювати таблиці. Індексатори дорого запускаються, особливо коли на сторінках категорій трафік, клієнти розміщують замовлення, а адміністратори зберігають продукти. При збереженні продукту кеш стає недійсним (поза темою). У випадку індексатора акцій, перед тим, як закінчити його виконання, він надсилає ідентифікатори сутнього об’єкта як теги кешу, які потрібно очистити (тип кешу повного сторінки). У категоріях Magento 2.0 надсилаються ідентифікатори придбаних товарів. У Magento 2.1 надсилаються ідентифікатори продукту.
Є 2 таблиці MySQL, які зберігають індексаторні коди та статуси:
indexer_state
mview_state
mview_state
працює Update by Schedule
в адміністраторі> Система> Управління індексаторами
Update by Schedule
змушує індексатори працювати в кроні.
Є 3 записи в Magento_Indexer/etc/contab.xml
:
<group id="index">
<job name="indexer_reindex_all_invalid" instance="Magento\Indexer\Cron\ReindexAllInvalid" method="execute">
<schedule>* * * * *</schedule>
</job>
<job name="indexer_update_all_views" instance="Magento\Indexer\Cron\UpdateMview" method="execute">
<schedule>* * * * *</schedule>
</job>
<job name="indexer_clean_all_changelogs" instance="Magento\Indexer\Cron\ClearChangelog" method="execute">
<schedule>0 * * * *</schedule>
</job>
</group>
indexer_reindex_all_invalid
ведеться далі indexer_state
. Існує ще потреба запустити "звичайні" індекси в cron
indexer_update_all_views
ведеться далі mview_state
indexer_clean_all_changelogs
- очищає журнали змін, якими користується mview_state
Зверніть увагу , що групові завдання хрон індексатор запускається в окремому процесі PHP, як заявлено в etc/contab_groups.xml
:
<use_separate_process>1</use_separate_process>
.
Таблиці змін є:
[indexer name]_cl
(суфіксом _cl
). напр cataloginventory_stock_cl
. Якщо у вас встановлено індексатори Update by Schedule
та зберігають продукт у адміністраторі, ви побачите entity_id
цей продукт у цій таблиці. Це велике коло, я думаю, що замовлення на замовлення або створення відправлення також додадуть сюди запис.
Хтось наводив приклад в офіційному розробнику про те, як створювати нові матеріалізовані представлення та які необхідні методи інтерфейсу (ігноруйте вищезазначене твердження про замовлення в фрагменті нижче):
<?php
<VendorName>\Merchandizing\Model\Indexer;
class Popular implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface
{
public function executeFull(); //Should take into account all placed orders in the system
public function executeList($ids); //Works with a set of placed orders (mass actions and so on)
public function executeRow($id); //Works in runtime for a single order using plugins
public function execute($ids); //Used by mview, allows you to process multiple placed orders in the "Update on schedule" mode
}
Це матиме сенс:
//public function execute($ids); Used by mview, allows you to process multiple **entities** in the "Update on schedule" mode
}
де $ids
параметр містить ідентифікатори сутностей з *_cl
таблиць.
Який зв'язок між недійсним кешем та індексаторами. Сторінки категорій тепер кешовані на повній сторінці (вбудований кеш на повній сторінці або через лак).
Є \Magento\Indexer\Model\Processor\InvalidateCache::afterUpdateMview
:
/**
* Update indexer views
*
* @param \Magento\Indexer\Model\Processor $subject
* @return void
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function afterUpdateMview(\Magento\Indexer\Model\Processor $subject)
{
if ($this->moduleManager->isEnabled('Magento_PageCache')) {
$this->eventManager->dispatch('clean_cache_after_reindex', ['object' => $this->context]);
}
}
Повернутися до Magento\Indexer\Cron\UpdateMview::execute()
:
/**
* Regenerate indexes for all invalid indexers
*
* @return void
*/
public function execute()
{
$this->processor->updateMview();
}
Magento\Indexer\Model\Processor::updateMview()
:
/**
* Update indexer views
*
* @return void
*/
public function updateMview()
{
$this->mviewProcessor->update('indexer');
}
В app/etc/di.xml
є:
<preference for="Magento\Framework\Mview\ProcessorInterface" type="Magento\Framework\Mview\Processor" />
/**
* Materialize all views by group (all views if empty)
*
* @param string $group
* @return void
*/
public function update($group = '')
{
foreach ($this->getViewsByGroup($group) as $view) {
$view->update();
}
}
Magento\Framework\Mview\ViewInterface
/**
* Materialize view by IDs in changelog
*
* @return void
* @throws \Exception
*/
public function update();
app/etc/di.xml
<preference for="Magento\Framework\Mview\ViewInterface" type="Magento\Framework\Mview\View" />
В Magento\Framework\Mview\View::update()
є:
$action = $this->actionFactory->get($this->getActionClass());
$this->getState()->setStatus(View\StateInterface::STATUS_WORKING)->save();
..
$action->execute($ids);
..
Якщо ви шукаєте в vendor/
каталозі, Magento\Framework\Mview\ActionInterface
ви знайдете, наприклад, це:
В \Magento\CatalogInventory\Model\Indexer
:
class Stock implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface
У цьому класі є:
/**
* Execute materialization on ids entities
*
* @param int[] $ids
*
* @return void
*/
public function execute($ids)
{
$this->_productStockIndexerRows->execute($ids);
}
І схоже, що він повертається до «нормального» класу методу виконання індексаторів, який використовується MView.
Про очищення кешу після індексатора акцій. Коли замовлення оформляється на замовлення, кількість віднімається за допомогою цього спостерігача:\Magento\CatalogInventory\Observer\SubtractQuoteInventoryObserver
$itemsForReindex = $this->stockManagement->registerProductsSale(
$items,
$quote->getStore()->getWebsiteId()
);
Крім того, інший спостерігач запускає індексатор (але не безпосередньо на Mview / Indexer за графіком):
\Magento\CatalogInventory\Observer\ReindexQuoteInventoryObserver
if ($productIds) {
$this->stockIndexerProcessor->reindexList($productIds);
}
У випадку Mview, коли нові величини віднімаються SubtractQuoteInventoryObserver
, тригер MySQL (створений для Mview) вставить рядок cataloginventory_stock_cl
, відзначаючи, що потрібно повторне виведення (запас та повний текст) для цих придбаних ідентифікаторів продуктів. Існує багато тригерів MySQL, створених для Mview. Побачити їх усіх SHOW TRIGGERS;
.
Коли продукт вийде з продажу після оформлення замовлення, ви побачите 2 рядки, вставлені в цю таблицю (Magento зберігає 2-кратний товарний запас у цих двох спостерігачів).
Коли cron запускає індексатор акцій у режимі Mview, ідентифікатори впливаного продукту (у M2.1) або ідентифікатори категорій (у M2.0) надсилаються в кеш-пам'ять як теги кеша. Під кешем я маю на увазі тип кешу на повній сторінці. Приклад: catalog_product_99
або інший формат тегів кеша, залежно від версії Magento. Те саме, коли Mview не ввімкнено.
\Magento\CatalogInventory\Model\Indexer\Stock\AbstractAction::_reindexRows
...
$this->eventManager->dispatch('clean_cache_by_tags', ['object' => $this->cacheContext]);
У Magento_PageCache є спостерігач, \Magento\PageCache\Observer\FlushCacheByTags
який буде очищати тип кешу повних сторінок за тегами. Це робиться для вбудованого кешу на повну сторінку. Код, пов'язаний з лаком, є в \Magento\CacheInvalidate\Observer\InvalidateVarnishObserver
.
Існує безкоштовне розширення, яке позбавить кеш-пам’яті на продуктах, що знаходяться на складі після замовлення клієнта:
https://github.com/daniel-ifrim/innovo-cache-improve
Очищення кеш-пам'яті лише для продуктів, що не є на складі після оформлення замовлення, було введено за замовчуванням Magento 2.2.x. Див \Magento\CatalogInventory\Model\Indexer\Stock\CacheCleaner
.
Я думаю, що виконання cron для індексатора Admin > Stores > Configuration > Advanced > System > Cron configuration options for group: index
має бути встановлено набагато більше 1 хвилини.
Mview
посилається на матеріалізовані представлення , що таке таблиці індексів.