Skip to content

Rewrite Rules: Sort only post IDs when selecting random content - #14809

Closed
aryanjasala wants to merge 11 commits into
WordPress:trunkfrom
aryanjasala:fix/64498-random-split-query
Closed

aryanjasala wants to merge 11 commits into
WordPress:trunkfrom
aryanjasala:fix/64498-random-split-query

Conversation

@aryanjasala

Copy link
Copy Markdown

Random content requests force WP_Query not to split the request, so ORDER BY RAND() runs on full wp_posts rows. The database copies every eligible row, including post_content, into a temporary table to sort it.

This removes wp_random_content_split_the_query() and its hook, both new in 7.2. The random order then applies to post IDs only, and the selected post is loaded by ID, from the object cache when there is one. WP_Query never caches a query whose ORDER BY contains RAND(, so each request still selects a new post.

Ten logged-out requests to /random/ with 200,000 posts (about 640 MB of content), MariaDB 11.4, data in the buffer pool:

Min Median Max
trunk 5.0 s 5.9 s 7.8 s
this PR 0.22 s 0.23 s 0.54 s

Tests: the "single query / full row" assertions are replaced with tests that:

  • the random query selects IDs only, with LIMIT 0, 1 and no SQL_CALC_FOUND_ROWS;
  • at most one more query loads the selected post by ID;
  • two requests with a persistent object cache both run the random query.

The unit test for the removed function is removed. Tests_Query passes locally (860 tests). The full benchmark is on the ticket.

Trac ticket: https://core.trac.wordpress.org/ticket/64498

Use of AI Tools

AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 5.5
Used for: Setting up the benchmark, writing the patch and tests, and drafting this description. I reviewed the code and ran the tests and the benchmark myself.


This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

Random content requests force WP_Query not to split the request, so
ORDER BY RAND() runs on full wp_posts rows. The database copies every
eligible row, including post_content, into a temporary table to sort it.

Let the request split as usual. The random order then applies to post
IDs and the selected post is loaded by ID, from the object cache when
available. Queries ordered by RAND() are never cached by WP_Query, so
each request still selects a new post.

With 200,000 posts (about 640 MB of content) on MariaDB 11.4 with the
data in the buffer pool, ten requests to /random/ took 5.0 to 7.8
seconds (median 5.9) before and 0.22 to 0.54 seconds (median 0.23)
after.

See #64498.
@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs.

Core Committers: Use this line as a base for the props when committing in SVN:

Props aryanjasala, peterwilsoncc, dhrupo, westonruter.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.


Props Bot commands

You can trigger Props Bot actions by commenting on this PR:

  • @propsbot add <username> to give props to a GitHub user. Requires write access.
  • @propsbot remove <username> to leave a user out of the props. Requires write access.
  • @propsbot refresh to refresh this list. Adding the props-bot label works too.

@github-actions

Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

@peterwilsoncc peterwilsoncc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code changes look good to me.

I've left a couple of notes about the test suite. I may end up pushing the changes myself so I can get this committed before my weekend starts (it's a long weekend in Melboure, Aus).

@peterwilsoncc

Copy link
Copy Markdown
Contributor

I've pushed the following changes to the test suite:

  • Added docblocks to each of the existing tests
  • The cache test was flawed as go_to() flushes the global cache so I've modified them and move it tests specific to WP::handle_random()
  • Added test for WP::handle_random() code paths.

Once I validated the tests are passing I will commit the changes.

@peterwilsoncc

peterwilsoncc commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

@propsbot add @dhrupo
@propsbot add @westonruter

@peterwilsoncc peterwilsoncc added the props-bot Adding this label triggers the Props Bot workflow for a PR. label Oct 30, 2026
@github-actions github-actions Bot removed the props-bot Adding this label triggers the Props Bot workflow for a PR. label Oct 30, 2026
wporg-sync pushed a commit that referenced this pull request Oct 30, 2026
Removes the filtering of `split_the_query` to `false` on random post redirects. As sorting queries randomly generates a temporary table, selecting `*` places all data in the temporary table, whereas selecting `ID` only places the post ID in the temporary table. The unsplit query can become inefficient on sites with a relatively few posts (ie, thousands not millions).

This removes the function `wp_random_content_split_the_query()` with a hard deprecation as it was not released to a production version of WordPress.

Additionally, the following changes have been made to the test suite:

* Tests ensuring random redirects are not cached are refactored to avoid the `$this->go_to()` method in the test suite as the helper method flushes the cache, causing the tests to be invalid
* Introduces tests covering `WP::handle_random()` specifically
* Adds docblocks to each and every test in `Tests_Query_RandomContentRedirect`

Developed in #14809.

Follow-up to r63767, r63906, r64402.

Props aryanjasala, peterwilsoncc, dhrupo, westonruter.
Fixes #64498.



git-svn-id: https://develop.svn.wordpress.org/trunk@65042 602fd350-edb4-49c9-b593-d223f7449a82
@github-actions

Copy link
Copy Markdown

A commit was made that fixes the Trac ticket referenced in the description of this pull request.

SVN changeset: 65042
GitHub commit: eed6f20

This PR will be closed, but please confirm the accuracy of this and reopen if there is more work to be done.

@github-actions github-actions Bot closed this Oct 30, 2026
wporg-sync pushed a commit to WordPress/WordPress that referenced this pull request Oct 30, 2026
Removes the filtering of `split_the_query` to `false` on random post redirects. As sorting queries randomly generates a temporary table, selecting `*` places all data in the temporary table, whereas selecting `ID` only places the post ID in the temporary table. The unsplit query can become inefficient on sites with a relatively few posts (ie, thousands not millions).

This removes the function `wp_random_content_split_the_query()` with a hard deprecation as it was not released to a production version of WordPress.

Additionally, the following changes have been made to the test suite:

* Tests ensuring random redirects are not cached are refactored to avoid the `$this->go_to()` method in the test suite as the helper method flushes the cache, causing the tests to be invalid
* Introduces tests covering `WP::handle_random()` specifically
* Adds docblocks to each and every test in `Tests_Query_RandomContentRedirect`

Developed in WordPress/wordpress-develop#14809.

Follow-up to r63767, r63906, r64402.

Props aryanjasala, peterwilsoncc, dhrupo, westonruter.
Fixes #64498.


Built from https://develop.svn.wordpress.org/trunk@65042


git-svn-id: http://core.svn.wordpress.org/trunk@64192 1a063a9b-81f0-0310-95a4-ce76da25c4cd
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.

2 participants