在官方文档中:
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://zh.wikipedia.org/wiki/Materialized_view
为什么我们需要重复表格。索引器的运行成本很高,尤其是当类别页面上有访问量,客户下订单且管理员保存产品时。在产品保存中,缓存将失效(关闭主题)。对于股票索引器,在结束执行之前,它将发送受影响的实体ID作为要清除的缓存标签(全页缓存类型)。在Magento 2.0类别中,发送购买产品的ID。在Magento 2.1中,将发送产品ID。
有2个MySQL表保留索引器代码和状态:
indexer_state
mview_state
mview_state
与Update by Schedule
管理员>系统>索引器管理一起使用
Update by Schedule
使索引器在cron中运行。
共有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进程中运行的cron索引组的任务,如声明etc/contab_groups.xml
:
<use_separate_process>1</use_separate_process>
。
变更日志表为:(
[indexer name]_cl
后缀为_cl
)。例如cataloginventory_stock_cl
。如果您将索引器设置为Update by Schedule
并将产品保存在admin entity_id
中,则在此表中将看到该产品的。这是一个很大的圈子,我在考虑下订单或创建装运将在此处添加一个条目。
有人在官方devdoc中提供了一个示例,说明如何创建新的实例化视图以及所需的接口方法(忽略上面有关代码段中的订单的声明):
<?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
}
where $ids
参数具有*_cl
表中的实体ID 。
缓存失效和索引器之间有什么联系?现在,类别页面已被整页缓存(内置的整页缓存或通过Varnish)。
有\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使用的“普通”索引器的execute方法。
关于 Stock Indexer之后的缓存清理。在结帐时下订单时,使用此观察者减去数量:\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
,表示需要对这些购买的产品ID进行重新索引(库存和全文)。为Mview创建了许多MySQL触发器。一起看到他们SHOW TRIGGERS;
。
当产品在结帐后缺货时,您会在该表中看到2行(Magento在这2个观察者中节省了2倍库存项目)。
当cron在Mview模式下运行股票索引器时,受影响的产品ID(在M2.1中)或类别ID(在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
指的是物化视图,这就是索引表。