En la documentación oficial:
https://devdocs.magento.com/guides/v2.3/extension-dev-guide/indexing.html
está el 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 significa Vista materializada, que es una instantánea de la base de datos en un momento determinado.
https://en.wikipedia.org/wiki/Materialized_view
¿Por qué necesitaríamos duplicar tablas? Los indexadores son costosos de ejecutar, especialmente cuando hay tráfico en las páginas de categorías, los clientes hacen pedidos y los administradores guardan productos. Al guardar el producto, el caché se invalida (fuera del tema). En el caso del indexador de existencias, antes de que finalice la ejecución, envía los identificadores de entidad afectados como etiquetas de caché para su limpieza (tipo de caché de página completa). En las categorías de Magento 2.0 se envían los identificadores de los productos comprados. En Magento 2.1 se envían los identificadores de producto.
Hay 2 tablas MySQL que mantienen códigos y estados del indexador:
indexer_state
mview_state
mview_state
funciona con Update by Schedule
Admin> Sistema> Gestión de indexador
Update by Schedule
hace que los indexadores se ejecuten en cron.
Hay 3 entradas en 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
se ejecuta en indexer_state
. Todavía existe la necesidad de ejecutar indexadores 'normales' en cron
indexer_update_all_views
se ejecuta en mview_state
indexer_clean_all_changelogs
- borra los registros de cambios utilizados por mview_state
Tenga en cuenta que las tareas de grupo cron indexador ejecutan en un proceso separado php, como se declara en etc/contab_groups.xml
:
<use_separate_process>1</use_separate_process>
.
Las tablas de registro de cambios son:
[indexer name]_cl
(con el sufijo _cl
). por ej cataloginventory_stock_cl
. Si tiene indexadores configurados Update by Schedule
y guardan un producto en admin, verá el entity_id
producto de ese producto en esta tabla. Es un gran círculo, estoy pensando que hacer un pedido o crear un envío también agregará aquí una entrada.
Alguien proporcionó un ejemplo en devdoc oficial sobre cómo crear nuevas vistas materializadas y cuáles son los métodos de interfaz requeridos (ignore la declaración anterior sobre los pedidos en el siguiente fragmento):
<?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
}
Esto tendrá sentido: el
parámetro //public function execute($ids); Used by mview, allows you to process multiple **entities** in the "Update on schedule" mode
}
Where $ids
tiene los identificadores de las entidades de las *_cl
tablas.
¿Cuál es el vínculo entre la invalidación de caché y los indexadores? Las páginas de categorías ahora están en caché de página completa (caché de página completa incorporada o a través de Varnish).
Hay \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]);
}
}
Volver a 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');
}
En app/etc/di.xml
hay:
<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" />
En Magento\Framework\Mview\View::update()
hay:
$action = $this->actionFactory->get($this->getActionClass());
$this->getState()->setStatus(View\StateInterface::STATUS_WORKING)->save();
..
$action->execute($ids);
..
Si busca en el vendor/
directorio Magento\Framework\Mview\ActionInterface
encontrará, por ejemplo, esto:
En \Magento\CatalogInventory\Model\Indexer
:
class Stock implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface
En esta clase hay:
/**
* Execute materialization on ids entities
*
* @param int[] $ids
*
* @return void
*/
public function execute($ids)
{
$this->_productStockIndexerRows->execute($ids);
}
Y parece que vuelve al método 'ejecutar' de la clase 'normal' de indexadores que utiliza MView.
Acerca de la limpieza de caché después de Stock Indexer. Cuando se realiza un pedido en la caja, las cantidades se restan utilizando este observador:\Magento\CatalogInventory\Observer\SubtractQuoteInventoryObserver
$itemsForReindex = $this->stockManagement->registerProductsSale(
$items,
$quote->getStore()->getWebsiteId()
);
Además, otro observador activa el indexador (pero no directamente en Mview / Indexer por Schedule):
\Magento\CatalogInventory\Observer\ReindexQuoteInventoryObserver
if ($productIds) {
$this->stockIndexerProcessor->reindexList($productIds);
}
En el caso de Mview, cuando se restan las nuevas cantidades SubtractQuoteInventoryObserver
, el activador MySQL (creado para Mview) insertará una fila cataloginventory_stock_cl
, lo que indica que se debe reindexar (stock y texto completo) a los identificadores de los productos comprados. Hay muchos desencadenadores MySQL creados para Mview. Véalos a todos con SHOW TRIGGERS;
.
Cuando un producto se agota después del pago, verá 2 filas insertadas en esa tabla (Magento ahorra 2 veces el artículo de stock en estos 2 observadores).
Cuando cron ejecuta el indexador de stock en modo Mview, los identificadores de producto afectados (en M2.1) o los identificadores de categoría (en M2.0) se envían a la limpieza de caché como etiquetas de caché. Por caché me refiero al tipo de caché de página completa. Ejemplo: catalog_product_99
u otro formato de etiqueta de caché según la versión de Magento. Lo mismo cuando Mview no está habilitado.
\Magento\CatalogInventory\Model\Indexer\Stock\AbstractAction::_reindexRows
...
$this->eventManager->dispatch('clean_cache_by_tags', ['object' => $this->cacheContext]);
Y Magento_PageCache tiene un observador \Magento\PageCache\Observer\FlushCacheByTags
que limpiará el tipo de caché de página completa por etiquetas. Lo hace para la memoria caché de página completa incorporada. El código relacionado con el barniz está en \Magento\CacheInvalidate\Observer\InvalidateVarnishObserver
.
Existe una extensión gratuita que negará la limpieza de la memoria caché en los productos que todavía están en existencia después de la salida del cliente:
https://github.com/daniel-ifrim/innovo-cache-improve
Limpieza de caché solo en productos agotados después de que se introdujo el pago en Magento 2.2.x. Ver \Magento\CatalogInventory\Model\Indexer\Stock\CacheCleaner
.
Estoy pensando que la ejecución cron para indexador Admin > Stores > Configuration > Advanced > System > Cron configuration options for group: index
debería establecerse en mucho más de 1 minuto.
Mview
refiere a vistas materializadas , que son las tablas de índice.