What I've done:
1) Load a JSON file containing data for 363 config entities (1 address_format, 362 subdivision config entities).
2) Start XHProf
3) Initialize each config entity, setSyncing(TRUE), save()
4) Stop XHProf

Attaching the xhprof. It clearly shows that significant time is spent invalidating cache tags (invalidateTagsOnSave()), and in ConfigEntityBase::preSave().

1) Would be great to find a way to invalidate cache tags only once per import.
This would require wrapping invalidateTagsOnSave() with a isSyncing() check, and having a way to invalidate the tags after the sync (a postSync() method?)

2) ConfigEntityBase::preSave() has this:

    // Ensure this entity's UUID does not exist with a different ID, regardless
    // of whether it's new or updated.
    $matching_entities = $storage->getQuery()
      ->condition('uuid', $this->uuid())
      ->execute();
    $matched_entity = reset($matching_entities);
    if (!empty($matched_entity) && ($matched_entity != $this->id()) && $matched_entity != $this->getOriginalId()) {
      throw new ConfigDuplicateUUIDException(String::format('Attempt to save a configuration entity %id with UUID %uuid when this UUID is already used for %matched', array('%id' => $this->id(), '%uuid' => $this->uuid(), '%matched' => $matched_entity)));
    }

This results in an entity query per save, taking up 25% of the total time. Ouch.
Alex Pott tells me that it should be safe to wrap at least that part with an isSyncing() check, but I haven't been able to confirm.

CommentFileSizeAuthor
54d8e45a81393.d8.xhprof.zip23.6 KBbojanz
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

bojanz’s picture

Issue summary: View changes
catch’s picture

We could optimize the merge query implementation on MySQL, that would halve the queries here.

Not sure moving things to the end will help unless we're repeatedly invalidating the same cache tag?

bojanz’s picture

Half of those 720 invalidations are for the same tag, done by ConfigEntityBase::invalidateTagsOnSave():

  protected function invalidateTagsOnSave($update) {
    Cache::invalidateTags($this->getEntityType()->getListCacheTags());
  }

The others are done by the config system for the individual saved entities.

larowlan’s picture

Entity query with config entities used to be a full scan each time, perhaps a uuid indexer service would be an option

Berdir’s picture

85% of the invalidateTags() problem is ChainedFast, again. #2422657: Skip fast chained cache backend during installer is related, but that only fixed it for the installer.

I kind of caused this, because what it id before was broken.

Trying to remember where I was writing this before. Right, comment #24 in #2289201: [Meta] Make drupal install and run within reasonable php memory limits so we can reset the memory requirements to lower levels. We need an issue for that. markAsOutdated() needs to be optimized so that it is not called multiple times, except something happens where we need it again. Unfortunately, I'm not quite sure what that something would be, and thinking about it, not sure if that really helps. Because we are actually writing and reading from the chained fast backend as well, when writing/reading.

But maybe a single mark as outdated for cache tags per request would be enough? Or maybe, just like we changed it for the installer, we shouldn't use the fast chained backend during during a config sync, but only do a single explicit invalidation (The problem once again is that we don't know all cache bins in the factory, so we don't know what to invalidate until it is actually called).

Wim Leers’s picture

Would be great to find a way to invalidate cache tags only once per import.

Related: #2241377: [meta] Profile/rationalise cache tags

bojanz’s picture

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Berdir’s picture

Status: Active » Closed (outdated)

I'm pretty sure this is outdated, cache tag invalidation will not re-invalidate the same cache tag more than once in a row and #3334489: ChainedFastBackend invalidates all items when cache tags are invalidated just landed, plus the install stuff mentioned above many years ago.

On 2, I'm not 100% sure it's safe to skip the check, you could absolutely copy & paste a config entity manually, forget to change the UUID and try to import it. I think back then we didn't have config entity query indexes, so this should be much faster now.