perf(2meet-data-optimizer): drive flat-sorted searches from the flat table
- A filtered search ordered by a flat column is rewritten to SELECT STRAIGHT_JOIN … FROM flat INNER JOIN wp_posts, with posts.ID tie-breaks (ours and plugin-appended) read as the equal flat post_id, so MariaDB sorts one table instead of looking every post up and sorting in a temporary table - Only when the routed conditions already require a flat row on the sort group, without the copy route or a selective post filter; filter tmdo_router_flat_first turns it off; split_the_query compares with the same rewrite - Verify: tests/live/run.php router (13/13); integration 522; dev36 page SQL Q07 263→147 ms, Q15 250→142 ms; fe.sh hourly_rate__desc 850→367 ms, ids == native - PR: PR-062c
This commit is contained in:
@@ -75,12 +75,12 @@ class PostQueryRouterFoundRowsTest extends TestCase {
|
||||
}
|
||||
|
||||
/** A routed query plus the SQL WordPress would build for it (page size 1). */
|
||||
private function routed(): array {
|
||||
private function routed( array $clause = array( 'key' => 'fr_price', 'value' => 15, 'compare' => '>=', 'type' => 'NUMERIC' ) ): array {
|
||||
global $wpdb;
|
||||
$query = new WP_Query();
|
||||
$query->set( 'post_type', 'fr_item' );
|
||||
$query->set( 'post_status', 'publish' );
|
||||
$query->set( 'meta_query', array( array( 'key' => 'fr_price', 'value' => 15, 'compare' => '>=', 'type' => 'NUMERIC' ) ) );
|
||||
$query->set( 'meta_query', array( $clause ) );
|
||||
$router = new TMDO_Post_Query_Router();
|
||||
$router->pre_get_posts( $query );
|
||||
|
||||
@@ -134,6 +134,86 @@ class PostQueryRouterFoundRowsTest extends TestCase {
|
||||
$this->assertNotSame( $after_write, wp_cache_get_last_changed( 'posts' ) );
|
||||
}
|
||||
|
||||
// ── flat-first: a filtered search ordered by a flat column ─────────────
|
||||
|
||||
/**
|
||||
* A routed search ordered by the flat price (named clause), with the
|
||||
* posts.ID tie-break a plugin such as HivePress appends.
|
||||
*
|
||||
* @return array{0:TMDO_Post_Query_Router, 1:WP_Query, 2:string}
|
||||
*/
|
||||
private function sorted( string $compare = '>=' ): array {
|
||||
global $wpdb;
|
||||
$query = new WP_Query();
|
||||
$query->set( 'post_type', 'fr_item' );
|
||||
$query->set( 'post_status', 'publish' );
|
||||
$query->set( 'meta_query', array( 'price' => array( 'key' => 'fr_price', 'value' => 15, 'compare' => $compare, 'type' => 'NUMERIC' ) ) );
|
||||
$query->set( 'orderby', 'price' );
|
||||
$query->set( 'order', 'DESC' );
|
||||
$router = new TMDO_Post_Query_Router();
|
||||
$router->pre_get_posts( $query );
|
||||
|
||||
$request = "SELECT SQL_CALC_FOUND_ROWS {$wpdb->posts}.ID FROM {$wpdb->posts} " . $router->posts_join( '', $query )
|
||||
. " WHERE 1=1 AND {$wpdb->posts}.post_type = 'fr_item' AND (({$wpdb->posts}.post_status = 'publish'))" . $router->posts_where( '', $query )
|
||||
. ' ORDER BY ' . $router->posts_orderby( '', $query ) . ", {$wpdb->posts}.ID DESC LIMIT 0, 10";
|
||||
return array( $router, $query, $request );
|
||||
}
|
||||
|
||||
public function test_sorted_filtered_request_drives_from_the_flat_table_with_the_same_rows(): void {
|
||||
global $wpdb;
|
||||
list( $router, $query, $request ) = $this->sorted();
|
||||
|
||||
$sql = $router->posts_request( $request, $query );
|
||||
|
||||
$this->assertStringStartsWith( 'SELECT STRAIGHT_JOIN ', $sql );
|
||||
$this->assertStringContainsString( 'FROM `' . self::TABLE . '` AS `wpdoflat_fr_item_fr_core` INNER JOIN ' . $wpdb->posts . ' ON', $sql );
|
||||
$this->assertStringNotContainsString( 'LEFT JOIN `' . self::TABLE . '`', $sql );
|
||||
$this->assertStringEndsWith( 'ORDER BY `wpdoflat_fr_item_fr_core`.`fr_price` DESC, `wpdoflat_fr_item_fr_core`.`post_id` DESC, `wpdoflat_fr_item_fr_core`.`post_id` DESC LIMIT 0, 10', $sql, 'posts.ID tie-breaks read the flat post_id' );
|
||||
$this->assertSame( array( '3', '2' ), $wpdb->get_col( $sql ) );
|
||||
$this->assertSame( $wpdb->get_col( str_replace( 'SQL_CALC_FOUND_ROWS ', '', $request ) ), $wpdb->get_col( $sql ) );
|
||||
}
|
||||
|
||||
public function test_date_ordered_filtered_request_keeps_wordpress_join_order(): void {
|
||||
list( $router, $query, $request ) = $this->routed();
|
||||
|
||||
$this->assertStringStartsNotWith( 'SELECT STRAIGHT_JOIN', $router->posts_request( $request, $query ) );
|
||||
}
|
||||
|
||||
public function test_flat_first_needs_a_condition_that_rejects_posts_without_a_flat_row(): void {
|
||||
list( $router, $query, $request ) = $this->sorted( 'NOT EXISTS' );
|
||||
|
||||
$this->assertStringStartsNotWith( 'SELECT STRAIGHT_JOIN', $router->posts_request( $request, $query ) );
|
||||
}
|
||||
|
||||
public function test_flat_first_is_skipped_for_selective_post_filters(): void {
|
||||
list( $router, $query, $request ) = $this->sorted();
|
||||
$query->set( 'post__in', array( 2 ) );
|
||||
|
||||
$this->assertStringStartsNotWith( 'SELECT STRAIGHT_JOIN', $router->posts_request( $request, $query ) );
|
||||
}
|
||||
|
||||
public function test_flat_first_can_be_turned_off(): void {
|
||||
list( $router, $query, $request ) = $this->sorted();
|
||||
$off = static fn() => false;
|
||||
add_filter( 'tmdo_router_flat_first', $off );
|
||||
try {
|
||||
$this->assertStringStartsNotWith( 'SELECT STRAIGHT_JOIN', $router->posts_request( $request, $query ) );
|
||||
} finally {
|
||||
remove_filter( 'tmdo_router_flat_first', $off );
|
||||
}
|
||||
}
|
||||
|
||||
public function test_flat_first_keeps_the_split_query(): void {
|
||||
global $wpdb;
|
||||
list( $router, $query, $request ) = $this->sorted();
|
||||
$old_request = str_replace( "{$wpdb->posts}.ID FROM", "{$wpdb->posts}.* FROM", $request );
|
||||
$query->request = $router->posts_request( $old_request, $query );
|
||||
$query->set( 'posts_per_page', 10 );
|
||||
|
||||
$this->assertStringStartsWith( 'SELECT STRAIGHT_JOIN ', $query->request );
|
||||
$this->assertTrue( $router->split_the_query( false, $query, $old_request, array( 'fields' => "{$wpdb->posts}.*", 'limits' => 'LIMIT 0, 10' ) ) );
|
||||
}
|
||||
|
||||
// ── split query: IDs first, then cached post objects ──────────────────
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user