Dans la documentation officielle:
https://devdocs.magento.com/guides/v2.3/extension-dev-guide/indexing.html
il y a le stement:
`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 signifie Materialized View, qui est un instantané de la base de données à un moment donné.
https://en.wikipedia.org/wiki/Materialized_view
Pourquoi aurions-nous besoin de dupliquer des tableaux. Les indexeurs sont coûteux à exécuter, en particulier lorsqu'il y a du trafic sur les pages de catégorie, les clients passent des commandes et les administrateurs enregistrent les produits. Lors de l'enregistrement du produit, le cache est invalidé (hors sujet). En cas d'indexeur de stock, avant de terminer l'exécution, il envoie les identifiants d'entité concernés en tant que balises de cache à nettoyer (type de cache pleine page). Dans les catégories Magento 2.0, les identifiants des produits achetés sont envoyés. Dans Magento 2.1, les identifiants des produits sont envoyés.
Il y a 2 tables MySQL qui conservent les codes et les états de l'indexeur:
indexer_state
mview_state
mview_state
fonctionne avec Update by Schedule
dans Admin> Système> Gestion de l'indexeur
Update by Schedule
rend les indexeurs à exécuter dans cron.
Il y a 3 entrées dans 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
est exécuté indexer_state
. Il est toujours nécessaire d'exécuter des indexeurs «normaux» dans cron
indexer_update_all_views
est exécuté sur mview_state
indexer_clean_all_changelogs
- efface les journaux des modifications utilisés par mview_state
Notez que les tâches du groupe indexeur cron exécuter dans un processus php séparé, tel que déclaré dans etc/contab_groups.xml
:
<use_separate_process>1</use_separate_process>
.
Les tables du journal des modifications sont:
[indexer name]_cl
(suffixées de _cl
). par exemple cataloginventory_stock_cl
. Si vous avez des indexeurs définis pour Update by Schedule
et enregistrez un produit dans admin, vous verrez le entity_id
de ce produit dans ce tableau. C'est un grand cercle, je pense que passer commande ou créer un envoi ajoutera ici une entrée également.
Quelqu'un a fourni un exemple dans devdoc officiel sur la façon de créer de nouvelles vues matérialisées et quelles sont les méthodes d'interface requises (ne tenez pas compte de la déclaration ci-dessus concernant les commandes dans l'extrait de code ci-dessous):
<?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
}
Cela aura un sens:
//public function execute($ids); Used by mview, allows you to process multiple **entities** in the "Update on schedule" mode
}
où le $ids
paramètre a les identifiants d'entités des *_cl
tables.
Quel est le lien entre l'invalidation du cache et les indexeurs. Les pages de catégories sont désormais mises en cache sur toute la page (cache de page complet intégré ou via Vernis).
Il y a \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]);
}
}
Retour à 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');
}
Il app/etc/di.xml
y a:
<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" />
Il Magento\Framework\Mview\View::update()
y a:
$action = $this->actionFactory->get($this->getActionClass());
$this->getState()->setStatus(View\StateInterface::STATUS_WORKING)->save();
..
$action->execute($ids);
..
Si vous recherchez dans le vendor/
répertoire pour Magento\Framework\Mview\ActionInterface
vous trouverez par exemple ceci:
Dans \Magento\CatalogInventory\Model\Indexer
:
class Stock implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface
Dans cette classe il y a:
/**
* Execute materialization on ids entities
*
* @param int[] $ids
*
* @return void
*/
public function execute($ids)
{
$this->_productStockIndexerRows->execute($ids);
}
Et il semble qu'il retourne à la classe «normale» des indexeurs, la méthode «execute» qui est utilisée par MView.
À propos du nettoyage du cache après Stock Indexer. Lorsqu'une commande est passée à la caisse, les quantités sont soustraites à l'aide de cet observateur:\Magento\CatalogInventory\Observer\SubtractQuoteInventoryObserver
$itemsForReindex = $this->stockManagement->registerProductsSale(
$items,
$quote->getStore()->getWebsiteId()
);
De plus, un autre observateur déclenche l'indexeur (mais pas directement sur Mview / Indexer by Schedule):
\Magento\CatalogInventory\Observer\ReindexQuoteInventoryObserver
if ($productIds) {
$this->stockIndexerProcessor->reindexList($productIds);
}
Dans le cas de Mview, lorsque les nouvelles quantités sont soustraites SubtractQuoteInventoryObserver
, le déclencheur MySQL (créé pour Mview) insérera une ligne dans cataloginventory_stock_cl
, marquant qu'une réindexation (stock et texte intégral) doit être effectuée pour les ID de produit achetés. Il existe de nombreux déclencheurs MySQL créés pour Mview. Voyez-les tous avec SHOW TRIGGERS;
.
Lorsqu'un produit est en rupture de stock après le paiement, vous verrez 2 lignes insérées dans ce tableau (Magento enregistre 2 fois l'article en stock dans ces 2 observateurs).
Lorsque cron exécute l'indexeur de stock en mode Mview, les identifiants de produit affectés (dans M2.1) ou les identifiants de catégories (dans M2.0) sont envoyés au cache clean en tant que balises de cache. Par cache, je veux dire le type de cache pleine page. Exemple: catalog_product_99
ou autre format de balise de cache selon la version de Magento. De même lorsque Mview n'est pas activé.
\Magento\CatalogInventory\Model\Indexer\Stock\AbstractAction::_reindexRows
...
$this->eventManager->dispatch('clean_cache_by_tags', ['object' => $this->cacheContext]);
Et Magento_PageCache a un observateur \Magento\PageCache\Observer\FlushCacheByTags
qui nettoiera le type de cache pleine page par des balises. Il le fait pour le cache pleine page intégré. Le code relatif au vernis est entré \Magento\CacheInvalidate\Observer\InvalidateVarnishObserver
.
Il existe une extension gratuite qui refusera le nettoyage du cache sur les produits encore en stock après le paiement du client:
https://github.com/daniel-ifrim/innovo-cache-improve
Nettoyage du cache uniquement sur les produits en rupture de stock après l'introduction de la commande dans Magento 2.2.x. Tu vois \Magento\CatalogInventory\Model\Indexer\Stock\CacheCleaner
.
Je pense que l'exécution de cron pour l'indexeur dans Admin > Stores > Configuration > Advanced > System > Cron configuration options for group: index
devrait être définie sur plus de 1 minute.
Mview
fait référence aux vues matérialisées , ce que sont les tables d'index.