4.2.1: Indexing Overview

4.2: Indexes

Indexing Overview

Indexing pre-calculates values. For example, the Inventory index aggregates the source quantity into the stock quantity. The Catalog Search Fulltext indexer pushes product data to ElasticSearch. And please don't forget the price indexer.

Without indexers, Magento would be very slow. Unusuably slow.

Unfortunately, very few developers know about indexing, let alone have made any changes to it. This section will make you familiar with the ins and outs of Magento indexing.

Let's look at the biggest concepts:

  • Indexers are declared in etc/indexer.xml. This implements \Magento\Framework\Indexer\ActionInterface.
  • Mview updates individual rows when running in Index on Schedule mode. Indexers prepared for this are implement \Magento\Framework\Mview\ActionInterface.
  • Mview relies on Magento-created triggers which add a row into the applicable _cl tables.
  • Indexers are run in three modes: executeFull, executeList, and executeRow.
  • What happens when a product is saved? This is where Mview kicks in. Mview initiates an action when a row is changed. This would typically happen in MySQL and kick off an action in MySQL. However, Magento intercepts these requests. You will find numerous tables with the _cl suffix. These tables contain records that need to be re-indexed. The mview_state table tracks these changes.
  • Magento recommends that indexing happen on a schedule (every minute) and NOT after save. This means your cron process needs to be very reliable.

Entry points


Let's discuss how indexers are kicked off. Cron is the most notable entry (although this is not always the case).

indexer_update_all_views -> Magento\Indexer\Cron\UpdateMview

  • This method iterates through the \Magento\Framework\Mview\View\Collection and calls update on each \Magento\Framework\Mview\View.
  • The rows to update are stored in tables ending in _cl.
  • mview_state stores the view IDs and the current version_id.
  • When this runs, the current version_id is compared with the version_id in the _cl table (cl is the abbreviation for change_log). The entity_id's that differ are indexed.

indexer_reindex_all_invalid -> \Magento\Indexer\Model\Processor::reindexAllInvalid

  • Each indexer is loaded in \Magento\Indexer\Model\Processor::reindexAllInvalid.
  • If an indexer is marked as invalid in indexer_state's status column, the entire index is rebuilt. Important: I've seen a number of cases where a 3rd-party module frequently marks an entire index as invalid. This is very bad for performance, and mview should be used instead.
  • The index is marked as working in \Magento\Indexer\Model\Indexer::reindexAll. Note that if there is a shared index (the catalog_category_product and catalog_product_category indexes, for example), the other one is suspended temporarily from reindexing.

Manual process

There is nothing stopping you from directly calling an indexer process, like this: \Magento\InventoryIndexer\Indexer\SourceItem\SourceItemIndexer::executeList()

You'll notice that the input parameters are different. In other words, you can't loop through all indexes and call executeList.

Indexer example

Further reading:

Complete and Continue