Magento 2 Partiële Herindexering

Marco de Vries

January 17, 2018

7 min lezen

Magento 2 treft veel maatregelen om de snelheid van de webshop te verhogen. Het heeft meer dan 30 index-tabellen om de shopping-ervaring voor de gebruiker aangenaam te maken, en daarnaast nog een flat product table en een flat category table per store view, als flat tables ingeschakeld zijn.

If you're seeking an English version of this article, please refer to this article.

Als database entiteiten als producten, categorieën en klanten aangepast worden, moeten deze indexen worden bijgewerkt. Magento heeft twee manieren om dit te doen, genaamd “Indexeren bij opslaan” (“Update on Save”) en “Volgens schema bijwerken” (“Update by Schedule”).

Ik zal de term “entiteiten” hier gebruiken voor zowel producten, categorieën als klanten.

Indexeren bij opslaan is het makkelijkst uit te leggen. Steeds als een entiteit wordt toegevoegd, gewijzigd, of verwijderd in de backend of via een REST request, worden alle noodzakelijke indexen bijgewerkt om deze wijziging op te vangen. Een groot aantal extra SQL queries worden uitgevoerd in hetzelfde request dat de entiteit toevoegt, bijwerkt, of verwijdert. De index wordt niet volledig opgebouwd, het wordt alleen een beetje aangepast. Specifieke onderdelen van caches worden direct geleegd om ervoor te zorgen dat de wijziging direct zichtbaar is op de webshop.

Volgens schema bijwerken past de indexen niet aan binnen het request. Het is zelfs zo dat Magento alleen die queries uitvoert die nodig zijn om de entiteit te wijzigen, en verder niks. Toch wordt de index bijgewerkt en specieke cache-onderdelen efficiënt geleegd binnen enkele minuten.

In de rest van dit blog artikel zal ik uitleggen hoe deze Volgens-schema-bijwerken-magie werkt.

Magento 2 treft veel maatregelen om de snelheid van de webshop te verhogen. Het heeft meer dan 30 index-tabellen om de shopping-ervaring voor de gebruiker aangenaam te maken, en daarnaast nog een flat product table en een flat category table per store view, als flat tables ingeschakeld zijn.

If you're seeking an English version of this article, please refer to this article.

Als database entiteiten als producten, categorieën en klanten aangepast worden, moeten deze indexen worden bijgewerkt. Magento heeft twee manieren om dit te doen, genaamd “Indexeren bij opslaan” (“Update on Save”) en “Volgens schema bijwerken” (“Update by Schedule”).

Ik zal de term “entiteiten” hier gebruiken voor zowel producten, categorieën als klanten.

Indexeren bij opslaan is het makkelijkst uit te leggen. Steeds als een entiteit wordt toegevoegd, gewijzigd, of verwijderd in de backend of via een REST request, worden alle noodzakelijke indexen bijgewerkt om deze wijziging op te vangen. Een groot aantal extra SQL queries worden uitgevoerd in hetzelfde request dat de entiteit toevoegt, bijwerkt, of verwijdert. De index wordt niet volledig opgebouwd, het wordt alleen een beetje aangepast. Specifieke onderdelen van caches worden direct geleegd om ervoor te zorgen dat de wijziging direct zichtbaar is op de webshop.

Volgens schema bijwerken past de indexen niet aan binnen het request. Het is zelfs zo dat Magento alleen die queries uitvoert die nodig zijn om de entiteit te wijzigen, en verder niks. Toch wordt de index bijgewerkt en specieke cache-onderdelen efficiënt geleegd binnen enkele minuten.

In de rest van dit blog artikel zal ik uitleggen hoe deze Volgens-schema-bijwerken-magie werkt.

Triggers

Een database trigger is een event handler die reageert op veranderingen in a database tabel.

Als een index ingesteld wordt op “Volgens schema bijwerken”, maakt Magento 2 er een aantal triggers voor aan. Voor catalog_product_flat alleen al worden 30 triggers aangemaakt. Ik zal er hier slechts 3 tonen:

mysql> show triggers \G
 
*************************** 1. row ***************************
             Trigger: trg_catalog_product_entity_after_insert
               Event: INSERT
               Table: catalog_product_entity
           Statement: BEGIN
INSERT IGNORE INTO `catalog_product_flat_cl` (`entity_id`) VALUES (NEW.`entity_id`);
END
              Timing: AFTER
             Created: 2018-01-10 16:04:59.54
            sql_mode: 
             Definer: some-magento-user@localhost
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: latin1_swedish_ci
*************************** 2. row ***************************
             Trigger: trg_catalog_product_entity_after_update
               Event: UPDATE
               Table: catalog_product_entity
           Statement: BEGIN
INSERT IGNORE INTO `catalog_product_flat_cl` (`entity_id`) VALUES (NEW.`entity_id`);
END
              Timing: AFTER
             Created: 2018-01-10 16:04:59.56
            sql_mode: 
             Definer: some-magento-user@localhost
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: latin1_swedish_ci
*************************** 3. row ***************************
             Trigger: trg_catalog_product_entity_after_delete
               Event: DELETE
               Table: catalog_product_entity
           Statement: BEGIN
INSERT IGNORE INTO `catalog_product_flat_cl` (`entity_id`) VALUES (OLD.`entity_id`);
END
              Timing: AFTER
             Created: 2018-01-10 16:04:59.57
            sql_mode: 
             Definer: some-magento-user@localhost
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: latin1_swedish_ci

De 3 triggers die je hier ziet corresponderen allen met veranderingen in de tabel “catalog_product_entity” (zie Table). De events zijn INSERT, UPDATE, en DELETE. Omdat er 10 tabellen bestaan die als bron dienen voor de inhoud van de materialized view catalog_product_flat, zijn er 3 x 10 = 30 triggers nodig om alle gevallen af te dekken.

De event handlers voor de “catalog_product_flat” index schrijven allemaal een enkele record in de changelog tabel “catalog_product_flat_cl”:

CREATE TABLE `catalog_product_flat_cl` (
  `version_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Version ID',
  `entity_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Entity ID',
  PRIMARY KEY (`version_id`)
) ENGINE=InnoDB AUTO_INCREMENT=118 DEFAULT CHARSET=utf8 COMMENT='catalog_product_flat_cl'

De version_id kolom is slechts een auto-increment veld.

De Cronjob Partiële Herindexering

In een doorsnee Magento installatie, runt de cron job ieder minuut. De cron job voert vele taken uit. Een van deze is “indexer_update_all_views”. Deze taak controleert voor iedere index of de version_id uit mview_state overeenkomt met de version_ids uit zijn changelog tabel.

De entity_ids van de changelog records met version_id groter dan de version_id uit mview_state worden verzameld, en de index wordt bijgewerkt voor deze entiteiten.

De cronjob leegt ook alle nodige caches. Dit gebeurt heel precies. Specifieke product-pagina en categorie-pagina caches worden geleegd. Niet de hele full page cache.

Daarna wordt de version_id in mview_state opgehoogd tot de hoogste version_id uit de changelog table.

Ieder uur verwijdert een andere cronjob, “indexer_clean_all_changelogs” alle changelog records met version_id kleiner dan die in mview_state.

Conclusie

Magento 2 stelt je in staat om producten van buiten af en van binnen uit te wijzigen. Ze kunnen niet alleen worden gewijzigd via the user interface (buiten), maar ook via direct database queries (binnen). “Volgens schema bijwerken” werkt de nodige indexen bij voor je.

Als je catalogus-producten wilt bijwerken op een manier die niet mogelijk is via Magento’s admin panel, of die sneller via een directe SQL query met phpMyAdmin of met een script kunnen worden uitgevoerd, dan is dit nog steeds mogelijk, zelfs op een productie webshop. Je hebt natuurlijk wel een goede kennis nodig van Magento’s MySQL tabellen. Maar de partiële herindexeringstechnieken van “Volgens schema bijwerken” zorgen ervoor dat alle noodzakelijke indexen en flat tables bijgewerkt worden, en dat zelfs specifieke caches geleegd worden.

Referenties

Hebben wij jouw interesse gewekt?

Laten we er eens over kletsen, onder het genot van een goede kop koffie!

neem contact op