From 4df383292182d0986254e7b70b7c66f0812d6e9a Mon Sep 17 00:00:00 2001 From: Corey McKrill <916023+coreymckrill@users.noreply.github.com> Date: Fri, 3 Jan 2025 17:03:53 -0800 Subject: [PATCH 1/3] Reduce queries while generating orders This makes a significant reduction in queries by storing lists of customer and product IDs in a runtime cache, rather than making new queries for those IDs every time an order is generated. The runtime cache does get refreshed every 100 orders, so that a greater variety of customers and products will be used. --- includes/Generator/Order.php | 64 ++++++++++++++++++---------------- includes/Generator/Product.php | 3 +- 2 files changed, 36 insertions(+), 31 deletions(-) diff --git a/includes/Generator/Order.php b/includes/Generator/Order.php index 11dc38f..0b6fd3c 100644 --- a/includes/Generator/Order.php +++ b/includes/Generator/Order.php @@ -7,6 +7,8 @@ namespace WC\SmoothGenerator\Generator; +use WC\SmoothGenerator\Util\RandomRuntimeCache; + /** * Order data generator. */ @@ -29,9 +31,6 @@ public static function generate( $save = true, $assoc_args = array() ) { $order = new \WC_Order(); $customer = self::get_customer(); - if ( ! $customer instanceof \WC_Customer ) { - return false; - } $products = self::get_random_products( 1, 10 ); foreach ( $products as $product ) { @@ -154,6 +153,10 @@ public static function batch( $amount, array $args = array() ) { $order_ids[] = $order->get_id(); } + // In case multiple batches are being run in one request, refresh the cache data. + RandomRuntimeCache::clear( 'customers' ); + RandomRuntimeCache::clear( 'products' ); + return $order_ids; } @@ -165,18 +168,25 @@ public static function batch( $amount, array $args = array() ) { public static function get_customer() { global $wpdb; - $guest = (bool) wp_rand( 0, 1 ); + if ( ! RandomRuntimeCache::exists( 'customers' ) ) { + $user_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->users} ORDER BY rand() LIMIT 100" ); + RandomRuntimeCache::set( 'customers', $user_ids ); + } + + Customer::disable_emails(); + + $customer = null; $existing = (bool) wp_rand( 0, 1 ); if ( $existing ) { - $total_users = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->users}" ); - $offset = wp_rand( 0, $total_users ); - $user_id = (int) $wpdb->get_var( "SELECT ID FROM {$wpdb->users} ORDER BY rand() LIMIT $offset, 1" ); // phpcs:ignore - return new \WC_Customer( $user_id ); + RandomRuntimeCache::shuffle( 'customers' ); + $customer_id = RandomRuntimeCache::get( 'customers', 1 )[0]; + $customer = new \WC_Customer( $customer_id ); } - Customer::disable_emails(); - $customer = Customer::generate( ! $guest ); + if ( is_null( $customer ) ) { + $customer = Customer::generate( false ); + } return $customer; } @@ -272,31 +282,25 @@ private static function get_status( $assoc_args ) { * @return array Random list of products. */ protected static function get_random_products( int $min_amount = 1, int $max_amount = 4 ) { - global $wpdb; - - $products = array(); - - $num_existing_products = (int) $wpdb->get_var( - "SELECT COUNT( DISTINCT ID ) - FROM {$wpdb->posts} - WHERE 1=1 - AND post_type='product' - AND post_status='publish'" - ); + if ( ! RandomRuntimeCache::exists( 'products' ) ) { + $query = new \WC_Product_Query( array( + 'limit' => 100, + 'return' => 'ids', + 'orderby' => 'rand', + ) ); - $num_products_to_get = wp_rand( $min_amount, $max_amount ); + $product_ids = $query->get_products(); - if ( $num_products_to_get > $num_existing_products ) { - $num_products_to_get = $num_existing_products; + RandomRuntimeCache::set( 'products', $product_ids ); } - $query = new \WC_Product_Query( array( - 'limit' => $num_products_to_get, - 'return' => 'ids', - 'orderby' => 'rand', - ) ); + RandomRuntimeCache::shuffle( 'products' ); + + $amount = wp_rand( $min_amount, $max_amount ); + $product_ids = RandomRuntimeCache::get( 'products', $amount ); + $products = array(); - foreach ( $query->get_products() as $product_id ) { + foreach ( $product_ids as $product_id ) { $product = wc_get_product( $product_id ); if ( $product->is_type( 'variable' ) ) { diff --git a/includes/Generator/Product.php b/includes/Generator/Product.php index b62fb9b..9c81fcc 100644 --- a/includes/Generator/Product.php +++ b/includes/Generator/Product.php @@ -141,7 +141,8 @@ public static function batch( $amount, array $args = array() ) { } // In case multiple batches are being run in one request, refresh the cache data. - RandomRuntimeCache::reset(); + RandomRuntimeCache::clear( 'product_cat' ); + RandomRuntimeCache::clear( 'product_tag' ); return $product_ids; } From acb06b556a1d31fed6e56dc7b718ec46c5cc7269 Mon Sep 17 00:00:00 2001 From: Corey McKrill <916023+coreymckrill@users.noreply.github.com> Date: Fri, 3 Jan 2025 17:18:48 -0800 Subject: [PATCH 2/3] Remove unnecessary method call --- includes/Generator/Order.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/includes/Generator/Order.php b/includes/Generator/Order.php index 0b6fd3c..bb02f08 100644 --- a/includes/Generator/Order.php +++ b/includes/Generator/Order.php @@ -173,8 +173,6 @@ public static function get_customer() { RandomRuntimeCache::set( 'customers', $user_ids ); } - Customer::disable_emails(); - $customer = null; $existing = (bool) wp_rand( 0, 1 ); From ddfbded5c6459b359f24a04a489e1405c7e137fd Mon Sep 17 00:00:00 2001 From: Corey McKrill <916023+coreymckrill@users.noreply.github.com> Date: Fri, 3 Jan 2025 17:58:07 -0800 Subject: [PATCH 3/3] Update odds of getting a guest customer --- includes/Generator/Order.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/includes/Generator/Order.php b/includes/Generator/Order.php index bb02f08..db411e3 100644 --- a/includes/Generator/Order.php +++ b/includes/Generator/Order.php @@ -166,17 +166,22 @@ public static function batch( $amount, array $args = array() ) { * @return \WC_Customer Customer object with data populated. */ public static function get_customer() { - global $wpdb; + $customer = null; if ( ! RandomRuntimeCache::exists( 'customers' ) ) { + global $wpdb; $user_ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->users} ORDER BY rand() LIMIT 100" ); RandomRuntimeCache::set( 'customers', $user_ids ); } - $customer = null; - $existing = (bool) wp_rand( 0, 1 ); + $guest_chances = 1; + if ( RandomRuntimeCache::count( 'customers' ) < 10 ) { + // Chance that customer is guest increases with fewer user accounts. + $guest_chances = 10 - RandomRuntimeCache::count( 'customers' ); + } + $guest = (bool) wp_rand( 0, $guest_chances ); - if ( $existing ) { + if ( ! $guest ) { RandomRuntimeCache::shuffle( 'customers' ); $customer_id = RandomRuntimeCache::get( 'customers', 1 )[0]; $customer = new \WC_Customer( $customer_id );