Skip to content

fix: reduce number of queries in layered navigation#387

Open
ahuininga-orisha wants to merge 2 commits into
developfrom
fix/229652-reduce-queries-layered-navigation
Open

fix: reduce number of queries in layered navigation#387
ahuininga-orisha wants to merge 2 commits into
developfrom
fix/229652-reduce-queries-layered-navigation

Conversation

@ahuininga-orisha

Copy link
Copy Markdown
Collaborator

Summary

When using the category link renderer in layered navigation, Tweakwise was issuing individual database queries for every category filter item — one query to load the category entity and another to resolve its URL rewrite. On a category page with many subcategory filter options this resulted in an N+1 query problem, slowing down page render time noticeably.

This fix batch-loads all category entities and their URL rewrites in two queries before the filter items are rendered, serving subsequent per-item lookups from an in-memory cache instead.

  • LinkRenderer: overrides getItems() to call StrategyHelper::warmUp() before returning items. This triggers a single batch load of all categories (including nested children) referenced by the filter, keyed by store ID to support multi-store setups.
  • StrategyHelper::warmUp(): added public method that collects all category IDs from the item tree (recursively), skips already-cached IDs, loads the remainder via CategoryCollectionFactory in one query, then bulk-loads their URL rewrites via UrlFinderInterface::findAllByData() in a second query. Loaded categories are stored in $categoryCache[categoryId][storeId].
  • StrategyHelper::getCategoryFromItem(): now checks $categoryCache before falling back to the single-row CategoryRepositoryInterface::get() call, eliminating per-item DB hits when warm-up ran.
  • StrategyHelper::preloadUrlRewrites(): sets request_path on each cached category object so Category::getUrl() skips its own URL rewrite lookup. Previously this method incorrectly passed all cached IDs instead of only the IDs just loaded — fixed to pass $loadedIds only.
  • Both files upgraded from the old phpcs:ignore DeclareStrictTypesMissing suppression to proper declare(strict_types=1); headers.

How to test

Scenario 1 — Category filter links render correctly

  1. Run setup:di:compile and cache:clean.
  2. Open a category page that uses the Tweakwise category link renderer (e.g. a category with subcategory facets enabled in the Tweakwise feed).
  3. Verify the category filter shows all subcategory options with correct labels and URLs.
  4. Click one of the subcategory filter links and verify it navigates to the correct subcategory URL.

Scenario 2 — No query regressions

  1. Enable query logging (e.g. via MAGE_MODE=developer + a query counter profiler or Blackfire).
  2. Load the same category page as Scenario 1.
  3. Confirm the number of url_rewrite and catalog_category_entity queries does not scale with the number of filter items — expect exactly 2 batch queries regardless of item count.

Scenario 3 — Multi-store

  1. Switch to a non-default store view.
  2. Load a category page with the category link filter.
  3. Verify filter links point to the correct store-scoped category URLs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant