diff --git a/core/lib/Drupal/Core/Cache/ApcuBackend.php b/core/lib/Drupal/Core/Cache/ApcuBackend.php index a275fe90456720c958ac2181bb42cee52f80d9fb..bf5e4d98ca9edfba54a6f2172ba4ce5892160962 100644 --- a/core/lib/Drupal/Core/Cache/ApcuBackend.php +++ b/core/lib/Drupal/Core/Cache/ApcuBackend.php @@ -98,6 +98,18 @@ public function getMultiple(&$cids, $allow_invalid = FALSE) { $result = apcu_fetch(array_keys($map)); $cache = []; if ($result) { + // Before checking the validity of each item individually, register the + // cache tags for all returned cache items for preloading, this allows the + // cache tag service to optimize cache tag lookups. + if ($this->checksumProvider instanceof CacheTagsChecksumPreloadInterface) { + $tags_for_preload = []; + foreach ($result as $item) { + if ($item->tags) { + $tags_for_preload[] = explode(' ', $item->tags); + } + } + $this->checksumProvider->registerCacheTagsForPreload(array_merge(...$tags_for_preload)); + } foreach ($result as $key => $item) { $item = $this->prepareItem($item, $allow_invalid); if ($item) { diff --git a/core/lib/Drupal/Core/Cache/CacheTagsChecksumTrait.php b/core/lib/Drupal/Core/Cache/CacheTagsChecksumTrait.php index 28af2ae2b8d2a3b6f4aaeebd45be84f48e1f45ec..a227b3da78f7967eeacd139d4f8647f380d2c995 100644 --- a/core/lib/Drupal/Core/Cache/CacheTagsChecksumTrait.php +++ b/core/lib/Drupal/Core/Cache/CacheTagsChecksumTrait.php @@ -182,7 +182,14 @@ public function reset() { * Implements \Drupal\Core\Cache\CacheTagsChecksumPreloadInterface::registerCacheTagsForPreload() */ public function registerCacheTagsForPreload(array $cache_tags): void { - $this->preloadTags = array_merge($this->preloadTags, $cache_tags); + if (empty($cache_tags)) { + return; + } + // Don't preload delayed tags that are awaiting invalidation. + $preloadable_tags = array_diff($cache_tags, $this->delayedTags); + if ($preloadable_tags) { + $this->preloadTags = array_merge($this->preloadTags, $preloadable_tags); + } } /** diff --git a/core/lib/Drupal/Core/Cache/DatabaseBackend.php b/core/lib/Drupal/Core/Cache/DatabaseBackend.php index efae811b7679a66c32a046fcd63058ce13913c7c..d5c9150dd389564cab4866408f5c608d093e691f 100644 --- a/core/lib/Drupal/Core/Cache/DatabaseBackend.php +++ b/core/lib/Drupal/Core/Cache/DatabaseBackend.php @@ -128,11 +128,23 @@ public function getMultiple(&$cids, $allow_invalid = FALSE) { // ::select() is a much smaller proportion of the request. $result = []; try { - $result = $this->connection->query('SELECT [cid], [data], [created], [expire], [serialized], [tags], [checksum] FROM {' . $this->connection->escapeTable($this->bin) . '} WHERE [cid] IN ( :cids[] ) ORDER BY [cid]', [':cids[]' => array_keys($cid_mapping)]); + $result = $this->connection->query('SELECT [cid], [data], [created], [expire], [serialized], [tags], [checksum] FROM {' . $this->connection->escapeTable($this->bin) . '} WHERE [cid] IN ( :cids[] ) ORDER BY [cid]', [':cids[]' => array_keys($cid_mapping)])->fetchAll(); } catch (\Exception) { // Nothing to do. } + // Before checking the validity of each item individually, register the + // cache tags for all returned cache items for preloading, this allows the + // cache tag service to optimize cache tag lookups. + if ($this->checksumProvider instanceof CacheTagsChecksumPreloadInterface) { + $tags_for_preload = []; + foreach ($result as $item) { + if ($item->tags) { + $tags_for_preload[] = explode(' ', $item->tags); + } + } + $this->checksumProvider->registerCacheTagsForPreload(array_merge(...$tags_for_preload)); + } $cache = []; foreach ($result as $item) { // Map the cache ID back to the original. diff --git a/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryAuthenticatedPerformanceTest.php b/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryAuthenticatedPerformanceTest.php index cccdaec2608f6374103fda2d019d3549cdee083b..2eebd63b88ae4b49f2fea470defa0ad432c7bdb1 100644 --- a/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryAuthenticatedPerformanceTest.php +++ b/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryAuthenticatedPerformanceTest.php @@ -63,7 +63,7 @@ public function testFrontPageAuthenticatedWarmCache(): void { 'CacheSetCount' => 0, 'CacheDeleteCount' => 0, 'CacheTagInvalidationCount' => 0, - 'CacheTagLookupQueryCount' => 4, + 'CacheTagLookupQueryCount' => 3, 'ScriptCount' => 2, 'ScriptBytes' => 123850, 'StylesheetCount' => 2,