hardening 2.4: 2meet-data-optimizer 1.4.0 (index-ordered routed sorts, date copy route, count invalidation) #8

Merged
wpdev merged 8 commits from hardening/2.4 into main 2026-09-27 23:40:31 +08:00
Owner

Release 2.4 — 2meet-data-optimizer 1.4.0 (hardening 2.4)

Routed sorts and date searches at million-listing scale (dev36 stage 3: 1.3M listings, 1.2M products, 62k vendors).

  • PR-118 flat-first sorts read the ID tie-break from flat post_id; indexes may end with the entity id column
  • PR-122 meta clauses without a value route as EXISTS (HivePress featured-listing lookup on every search page)
  • PR-123 live tools never flush the object cache
  • PR-127 migration engine keeps post status/date copies
  • PR-128 status/date copy route drops GROUP BY; index (post_status, post_date, post_id)
  • PR-129 migration engine rebuilds invalidate cached routed counts

dev36 front end (routed vs native): price range 0.34 s / 6.0 s, price sort 0.37 / 14 s, hourly sort 0.35 / 11.5 s, rating sort 0.51 / 43 s, keyword + price 0.59 / 8.8 s; ids/found equal to native (tie order in flat-first sorts follows the sort direction, PR-118).

Verify: composer test 704, test:integration 598, phpcs 0, stan OK.
Upgrade: run wp tmdo post-status-sync once on sites with status/date copies.

🤖 Generated with Claude Code

https://claude.ai/code/session_01U9oVDuhVvJnmARBmtue7rt

Release 2.4 — 2meet-data-optimizer 1.4.0 (hardening 2.4) Routed sorts and date searches at million-listing scale (dev36 stage 3: 1.3M listings, 1.2M products, 62k vendors). - PR-118 flat-first sorts read the ID tie-break from flat post_id; indexes may end with the entity id column - PR-122 meta clauses without a value route as EXISTS (HivePress featured-listing lookup on every search page) - PR-123 live tools never flush the object cache - PR-127 migration engine keeps post status/date copies - PR-128 status/date copy route drops GROUP BY; index (post_status, post_date, post_id) - PR-129 migration engine rebuilds invalidate cached routed counts dev36 front end (routed vs native): price range 0.34 s / 6.0 s, price sort 0.37 / 14 s, hourly sort 0.35 / 11.5 s, rating sort 0.51 / 43 s, keyword + price 0.59 / 8.8 s; ids/found equal to native (tie order in flat-first sorts follows the sort direction, PR-118). Verify: composer test 704, test:integration 598, phpcs 0, stan OK. Upgrade: run `wp tmdo post-status-sync` once on sites with status/date copies. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01U9oVDuhVvJnmARBmtue7rt
wpdev added 8 commits 2026-09-27 23:32:30 +08:00
- mut.php called wp_cache_flush() after each write and qbench.php
  wp_cache_flush_group() before each run; with Redis Object Cache's selective
  flush both are one server-side Lua scan over the site's keys, which blocked
  the shared Redis for 5–20 s on dev36 (3 M keys) and broke other sites'
  requests (BUSY / read errors)
- mut.php clears the touched post or user caches plus the runtime cache;
  qbench.php bumps the routed count version (posts' last_changed before 1.3.0)
- tests/ is not packaged; plugin code does not flush
- a group index may end with the entity ID column (post_id, ...)
- flat-first rewrites the posts.ID tie-breaks once, in the sort's direction:
  with a (column, post_id) index MySQL returns rows in order instead of
  sorting the whole match. dev36 (1.3M listings), price range sorted by price:
  850 ms filesort -> 2 ms. Ties are ordered by ID the same way as the column
  (natively ID DESC); pagination stays stable, result sets are unchanged
- Verify: EntityRegistryIndexesTest, PostQueryRouterFoundRowsTest (ASC
  tie-break, single tie-break), unit 704, integration 589, phpcs, stan;
  dev36 with the HivePress indexes (PR-119)
- PR: PR-118
- WP_Meta_Query adds a value condition only when 'value' is set, so a clause
  like array( 'key' => 'hp_featured' ) only tests that the key exists. The
  router read it as "= ''", declined it, and kept the whole query native
- HivePress runs such a query on every listing search page (featured-listing
  lookup in Attribute::set_search_query(): hp_featured plus the search's own
  filters, ORDER BY RAND()); at 1.3M listings on dev36 it took 2.26 s of a
  2.5 s page, routed or not
- Verify: PostQueryRouterTest (key-only clause routes as IS NOT NULL),
  integration 590, unit 704, phpcs, stan; dev36 front-end
- PR: PR-122
- HivePress runs it on every listing search page from its own
  pre_get_posts: get_posts() with the search's meta query (still unrouted,
  including its sort group), meta_key hp_featured and orderby rand. The
  router declined both shapes, so the lookup stayed native: 2.26–2.38 s of a
  2.5 s page at 1.3M listings on dev36
- a sort group (key NOT EXISTS OR key EXISTS) that no orderby uses matches
  every post and is dropped; meta_key without meta_value and without a
  meta_value sort routes as EXISTS (WP_Query turns it into that clause)
- Verify: PostQueryRouterTest (featured lookup routed, meta_key with a value
  untouched), integration 592, unit 704, phpcs, stan; dev36 front-end
- PR: PR-122 (follow-up)
- migrate_entity() (drift-check --fix, per-row backfill) REPLACEs the whole
  flat row and left out the post_status / post_date copies, so a rebuilt row
  had NULL status. One such row turns the status/date copy route off for the
  whole group: on dev36 a single row rebuilt by the stage-3 drift fix made the
  date-ordered price search 1.47 s instead of driving from the flat index
- post rows now carry TMDO_Post_Status_Sync::insert_columns(); the bulk pivot
  backfill (ON DUPLICATE KEY UPDATE) was not affected
- Verify: PostStatusSyncTest (existing and new rows keep their copies),
  integration 593, unit 704, phpcs, stan; dev36 post-status-sync + front-end
- PR: PR-127 (found in 2.4 profiling)
- Copy route: drop WordPress's GROUP BY when the flat row is the only join,
  and read posts.ID tie-breaks as the flat post_id (own direction, once)
- Post status sync: index (post_status, post_date, post_id) replaces the
  two-column idx_post_status_date (added / dropped by post-status-sync)
- dev36, 235k of 1.3M listings in a price range: main query 1.7 s -> 3 ms
- Verify: composer test (704), test:integration (597), phpcs, stan
- PR: PR-128
- migrate_entity (drift-check --fix), migrate_group and migrate_group_batch
  write flat rows outside the Hook Bus: bump the routed count version
  (once per call / batch; not on dry runs; post rows only)
- dev36: a vendor search kept counting 21515 of 21522 matches after a fix
- Verify: composer test (704), test:integration (598), phpcs, stan
- PR: PR-129
chore(2meet-data-optimizer): 1.4.0 release notes and version
Anti-EAV Lint + Quality Gate / anti-eav-lint (pull_request) Successful in 27s
Tests / Unit Tests (pull_request) Successful in 44s
Tests / PHP Lint (pull_request) Successful in 27s
Tests / PHPCS (pull_request) Successful in 35s
Tests / Integration Tests (pull_request) Successful in 1m41s
Tests / PHPStan (pull_request) Successful in 1m23s
13c4a1bcb9
- CHANGELOG / readme: PR-118, 122, 123, 127, 128, 129; upgrade step
  `wp tmdo post-status-sync` for the three-column copy index
- Version 1.3.0 -> 1.4.0 (header, TMDO_VERSION, Stable tag)
- PR: PR-124
wpdev closed this pull request 2026-09-27 23:37:18 +08:00
wpdev reopened this pull request 2026-09-27 23:37:22 +08:00
wpdev merged commit b30baeddf0 into main 2026-09-27 23:40:31 +08:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: wpdev/2meet-data-optimizer#8