MyCart Issues & Issues with Search AJAX & Site speed

This topic has 11 replies, 3 voices, and was last updated 1 month, 1 week ago ago by Andrew Mitchell

  • Avatar: Narka
    Narka
    Participant
    November 28, 2025 at 10:12

    Hey guys,

    Mycart and the entire shopping process including search is extremely slow. Can you please help me out?

    Please, contact administrator
    for this information.
    10 Answers
    Avatar: Rose Tyler
    Rose Tyler
    Support staff
    November 28, 2025 at 12:46

    Hello,

    We have noticed that your website is utilizing a large number of plugins. This could potentially impact the website’s performance, lead to errors, and affect its overall speed. To ensure optimal functionality and avoid such issues, we kindly ask you to manually review each plugin currently in use on your website.

    Additiaonly, please read this article – https://www.8theme.com/documentation/xstore/troubleshooting/the-ultimate-2025-guide-to-boosting-wordpress-speed-with-xstore-theme/

    Best regards,
    8Theme’s Team

    Avatar: Narka
    Narka
    Participant
    July 14, 2026 at 22:04

    XStore support request — WooCommerce product search results page is extremely slow (N+1 query loop)

    Site: argostheclassics.com
    Theme: XStore (xstore-child) · Builder: Elementor Pro (Theme Builder active) · WooCommerce, PHP 8.2.31
    Catalogue size: ~7,674 published products · No persistent object cache

    Symptom

    The WooCommerce product search results page (e.g. /?s=lamp&post_type=product) takes ~15–18 seconds to load. The regular Shop page and product category archives load in ~1.2 seconds, so the problem is specific to the search-results rendering, not the server or the catalogue in general.

    What we measured (Query Monitor)

    On a product search results page:

    ~1,050–1,125 database queries, totalling ~19 seconds of DB time
    No single query is slow — the slowest is ~0.8s. It’s an N+1 loop, i.e. many repeated queries, not one heavy query.

    The duplicated queries (all attributed by Query Monitor to the component et-core-plugin):

    A product query using SQL_CALC_FOUND_ROWS … FROM wp_posts LEFT JOIN wp_term_relationships … runs ~350 times
    A term lookup SELECT t.term_id FROM wp_terms INNER JOIN wp_term_taxonomy … runs ~370 times
    Plus ~135 repeated wp_options lookups and ~50 wp_postmeta lookups

    The same page rendered as a normal product archive (Shop) does not produce this loop.

    Our read of the cause

    There is no Theme Builder template for the WooCommerce search results page, so product search falls back to XStore’s own rendering path, which appears to run a per-result product/term query loop. FiboSearch also flagged “there is no correct template in the Elementor Theme Builder for the WooCommerce search results page.”

    What we already tried (did not fix it)

    Added an Elementor Theme Builder display condition “Search Results” to the existing “Products Archive” template (the one that makes the Shop fast), keeping its “All Product Archives” condition intact.
    Cleared Elementor → Tools → Clear Files & Data.
    Re-tested with fresh search terms: search results still render via et-core (still ~1,050 queries / ~15s), so the Elementor template is not overriding XStore’s search-results output.

    Question for XStore support

    How can we make the WooCommerce product search results page render with the same efficient product loop as the Shop / product archive (which is fast), instead of the current et-core rendering that produces this N+1?

    Specifically:

    Is there an XStore theme option that controls the search-results layout / lets it reuse the shop archive template?
    Is there a filter/hook or snippet to route product search (is_search() && post_type=product) through the standard archive rendering?
    Is this a known N+1 on large catalogues, and is there a recommended fix or update?

    Happy to provide the full Query Monitor export or temporary admin access if helpful.

    Avatar: Narka
    Narka
    Participant
    July 15, 2026 at 00:33

    Follow-up — same search code path, additional bug (SQL syntax error on apostrophes)
    Site: argostheclassics.com (XStore + Elementor Pro Theme Builder, WooCommerce, PHP 8.2).
    On top of the slow product-search results page (the N+1 loop I reported), the same search path also throws a SQL syntax error whenever a search term contains an apostrophe (‘).
    Example — searching Children’s bed or Children’s bed montessori logs:
    WordPress database error: You have an error in your SQL syntax … near ”s bed%” … for query SELECT SQL_CALC_FOUND_ROWS aor_posts.ID FROM aor_posts LEFT JOIN aor_term_relationships … AND meta_value LIKE ‘%Children’s bed%’
    The apostrophe isn’t escaped before being placed in the LIKE clause, so the query breaks. The call stack points to the theme’s search rendering: …/themes/xstore/header.php → ETC\App\Controllers\Elementor\General\Search->render → WP_Query.
    Impact: any customer searching a term with an apostrophe (e.g. “children’s”, “kids'”) gets a broken/empty result. It generated 7,500+ database errors (~20 MB of logs) in a short window. Because unescaped user input is reaching raw SQL, this is also an input-sanitization / security concern, not only a UX bug.
    Please fix the escaping of the search term in the product-search SQL ($wpdb->prepare / esc_sql). This is the same et-core search path as the performance issue, so ideally both are fixed together. Happy to share a full log sample or temporary admin access.

    Avatar: Andrew Mitchell
    Andrew Mitchell
    Support staff
    July 15, 2026 at 06:50

    Hello, Narka,

    Unfortunately, the FTP access details you provided are not working, so we are unable to apply the fix ourselves (please see the attached files for details). Therefore, we kindly ask you to add the following code to the functions.php file of your child theme.

    /**
     * Keep product search SQL safe when Elementor Product Grid searches by SKU.
     */
    add_filter( 'posts_search', 'xstore_child_prepare_product_search_by_sku', 9999, 2 );
    function xstore_child_prepare_product_search_by_sku( $search, $query ) {
    	if ( is_admin() || ! ( $query instanceof WP_Query ) || ! $query->is_search() ) {
    		return $search;
    	}
    
    	$search_term = $query->get( 's' );
    	if ( '' === (string) $search_term || ! get_theme_mod( 'search_by_sku_et-desktop', 1 ) ) {
    		return $search;
    	}
    
    	$post_type = $query->get( 'post_type' );
    	$is_product_query = ( 'product' === $post_type ) || ( is_array( $post_type ) && in_array( 'product', $post_type, true ) );
    	if ( ! $is_product_query ) {
    		return $search;
    	}
    
    	global $wpdb;
    
    	$like = '%' . $wpdb->esc_like( $search_term ) . '%';
    
    	return $wpdb->prepare(
    		" AND (
    			{$wpdb->posts}.post_title LIKE %s
    			OR {$wpdb->posts}.post_excerpt LIKE %s
    			OR {$wpdb->posts}.post_content LIKE %s
    			OR EXISTS (
    				SELECT 1
    				FROM {$wpdb->postmeta} product_sku
    				WHERE product_sku.meta_key = '_sku'
    				AND product_sku.meta_value LIKE %s
    				AND product_sku.post_id = {$wpdb->posts}.ID
    			)
    			OR {$wpdb->posts}.ID IN (
    				SELECT variation.post_parent
    				FROM {$wpdb->posts} variation
    				INNER JOIN {$wpdb->postmeta} variation_sku
    					ON variation_sku.post_id = variation.ID
    				WHERE variation.post_type = 'product_variation'
    				AND variation.post_status = 'publish'
    				AND variation.post_parent > 0
    				AND variation_sku.meta_key = '_sku'
    				AND variation_sku.meta_value LIKE %s
    			)
    		)",
    		$like,
    		$like,
    		$like,
    		$like,
    		$like
    	);
    }

    Best regards,
    8Theme Team

    Files is visible for topic creator and
    support staff only.
    Avatar: Narka
    Narka
    Participant
    July 16, 2026 at 10:15

    Hi Andrew,

    Thanks for the snippet. We added it to the child theme’s functions.php and confirmed it’s active (the function loads, posts_search is hooked, and we cleared OPcache) — but apostrophe searches still generate ~300 You have an error in your SQL syntax entries each. So the broken meta_value LIKE ‘%…%’ clause isn’t passing through the posts_search filter your snippet targets — it appears to be built as raw/secondary queries inside the et-core search render loop (where the snippet’s is_search() guard skips them). It looks like the fix needs to live inside et-core itself.

    To make that easy, we’ve created a dedicated FTP account for you. Access details are below.

    Notes

    The account is scoped to wp-content, so you have full access to the theme and et-core plugin. If you need anything outside that (e.g. the raw error_log or to toggle WP debug constants), just let me know and I’ll provide it.

    Current XStore Core is 5.7.6 — the issue reproduces on it with any apostrophe search term (e.g. children’s desk).
    Please let me know once you’re finished so I can remove the access.

    Please contact administrator
    for this information.
    Avatar: Andrew Mitchell
    Andrew Mitchell
    Support staff
    July 16, 2026 at 14:41

    Thank you for providing access. We have removed the fix from the child theme and made changes to the file wp-content/plugins/et-core-plugin/app/controllers/elementor/general/product-grid.php.

    Please check whether this has resolved your issue. If so, this fix will be included in the next theme update.

    Best regards,
    8Theme Team

    Avatar: Narka
    Narka
    Participant
    July 16, 2026 at 15:14

    Hi team,

    Thanks for the changes. Unfortunately the issue is not resolved — I re-tested under controlled conditions (emptied the error log, reset PHP OPcache so your edited plugin compiled fresh, then ran three product searches containing apostrophes).
    Result: 909 SQL syntax errors logged — exactly 303 per search, identical to before your edit. The pages return HTTP 200 only because WordPress suppresses the DB errors and still renders.
    The exact failing query and error:

    WordPress database error You have an error in your SQL syntax … near ‘s wardrobe%’
    for query SELECT SQL_CALC_FOUND_ROWS aor_posts.ID
    FROM aor_posts INNER JOIN aor_postmeta ON ( aor_posts.ID = aor_postmeta.post_id )
    … AND aor_posts.post_type = ‘product’ …
    The unescaped LIKE clauses being generated:
    LIKE ‘%kid’s wardrobe%’
    LIKE ‘%baker’s table%’
    LIKE ‘%children’s desk%’
    Two important points:

    In the same request, WordPress core’s own search query escapes the apostrophe correctly (LIKE ‘%kid\’s%’). Only the theme’s query is unescaped — so this is the theme building a LIKE fragment with the raw search term rather than passing it through $wpdb->prepare() / esc_like().

    The broken query is a SELECT SQL_CALC_FOUND_ROWS … FROM aor_posts INNER JOIN aor_postmeta with a _price meta filter — this is not the Elementor product-grid render path you edited in product-grid.php. The unescaped term is being injected into the main product search query (the price/meta filtered one), so the fix needs to go wherever that search LIKE is constructed.

    The FTP access is still active so you can apply the corrected fix directly. Please let me know once you’ve pushed it and I’ll re-run the same test.

    Thanks!

    ______

    Hi team,
    I traced the actual source. Your product-grid.php change is written correctly (it uses esc_like + $wpdb->prepare), but it only applies to the Elementor Product Grid widget’s query — not the main search results query. That’s why the error count is unchanged: still exactly 303 SQL syntax errors per apostrophe search.
    The real bug is in the theme:
    File: wp-content/themes/xstore/framework/theme-functions.php
    Function: etheme_search_post_excerpt() (added to posts_where by etheme_search_all_sku_query())
    At line 853 the search term is taken unescaped:
    php$s = $wp_the_query->query_vars[‘s’];
    and then interpolated raw into LIKE clauses at lines 864, 893, 939, 940, 941, 946, e.g.:
    php… AND meta_value LIKE ‘%$s%’
    … post_title LIKE ‘%$s%’
    Any search containing an apostrophe (kid’s wardrobe, baker’s table) breaks the SQL: error in your SQL syntax … near ‘s wardrobe%’.
    Fix — escape $s at line 853, which covers all six LIKE sites at once:
    php$s = esc_sql( $wp_the_query->query_vars[‘s’] );
    Or the fully-correct version (also neutralises user-typed %/_ wildcards):
    phpglobal $wpdb;
    $s = esc_sql( $wpdb->esc_like( $wp_the_query->query_vars[‘s’] ) );
    FTP is still active. Once you push it I’ll re-run the apostrophe test and confirm a clean log.

    Thanks!

    Avatar: Andrew Mitchell
    Andrew Mitchell
    Support staff
    July 17, 2026 at 08:01

    Hello, Narka,

    Thank you for your detailed investigation. You were correct: the previous change addressed the Elementor Product Grid query but not the main WooCommerce product search query.

    We have now corrected the etheme_search_post_excerpt() function in framework/theme-functions.php as follows:
    – Search terms are processed with wp_unslash() and $wpdb->esc_like().
    – All LIKE values are passed through $wpdb->prepare().
    – The filter now uses the current WP_Query instance instead of the global query, preventing search conditions from being injected into unrelated secondary queries.

    We tested the following searches:
    – kid’s wardrobe
    – baker’s table
    – children’s desk

    All returned HTTP 200 responses without adding any SQL syntax errors to the WordPress, PHP, or Nginx logs.

    Please perform the same controlled test on your installation after deploying the updated file and let us know the results.

    Best regards,
    8Theme Team

    Avatar: Narka
    Narka
    Participant
    July 17, 2026 at 11:38

    Hi team — your latest fix resolved the apostrophe SQL errors, but it broke the product search results page: every search returned “no products.”

    Root cause: the new etheme_search_parent_products_by_variation_sku function (hooked to posts_search, priority 999) leaks WordPress’s %-wildcard placeholder into the final SQL — the executed query contains LIKE ‘{hash}term{hash}’ instead of LIKE ‘%term%’, so it matches nothing. It also matches the full phrase rather than individual words. This function isn’t in our pre-fix backup, so it was introduced in this update.

    To keep the live store working, we’ve temporarily disabled that single filter via a must-use plugin, which restores native word-based search (verified: multi-word searches return correct products, apostrophe searches still produce 0 SQL errors). Please correct the placeholder handling in that function (the % wildcards must survive $wpdb->prepare()), and confirm word-based multi-term matching. FTP access is still active. Once you’ve shipped the corrected version we’ll remove our temporary plugin and re-test.

    ________

    I traced exactly why the new fix broke the product search. The problem is the new function etheme_search_parent_products_by_variation_sku() (in wp-content/themes/xstore/framework/theme-functions.php, registered at line 1007, defined at line 1012). It has two bugs:
    Bug 1 — it replaces the core search instead of extending it (breaks multi-word search).
    The function ignores the incoming $search (which contains WordPress’s word-split logic) and returns a brand-new clause that matches the whole phrase: $like = ‘%’ . $wpdb->esc_like( $search_term ) . ‘%’ → post_title LIKE ‘%pink chair%’. No product title contains the literal contiguous string “pink chair”, so every multi-word search returns zero results. It needs to merge its SKU condition into $search, not replace it.
    Bug 2 — the % wildcards leak as placeholder tokens (matches nothing).
    $wpdb->prepare( ” … LIKE %s”, $like ) where $like already contains % causes prepare() to placeholder-escape those % into its internal {hash} markers. Because the string is returned via the posts_search filter, remove_placeholder_escape() isn’t applied to it, so the executed SQL literally contains:
    LIKE ‘{bc631d548e…}pink chair{bc631d548e…}’
    — i.e. it searches for the literal text {hash}pink chair{hash}, matching nothing. You must call $wpdb->remove_placeholder_escape() on the prepared fragment.
    Here’s a corrected version that fixes both — it keeps WordPress’s word-split title/content search and adds the SKU/variation match as an OR:
    phpadd_filter( ‘posts_search’, ‘etheme_search_parent_products_by_variation_sku’, 999, 2 );
    function etheme_search_parent_products_by_variation_sku( $search, $query ) {
    if ( is_admin() || ! ( $query instanceof WP_Query ) || ! $query->is_search() ) {
    return $search;
    }
    $search_term = $query->get( ‘s’ );
    if ( ” === (string) $search_term || ! get_theme_mod( ‘search_by_sku_et-desktop’, 1 ) ) {
    return $search;
    }
    $post_type = $query->get( ‘post_type’ );
    $is_product_query = ( ‘product’ === $post_type ) || ( is_array( $post_type ) && in_array( ‘product’, $post_type, true ) );
    if ( ! $is_product_query ) {
    return $search;
    }

    global $wpdb;
    $like = ‘%’ . $wpdb->esc_like( $search_term ) . ‘%’;

    // Build ONLY the extra SKU / variation-SKU condition — do NOT rebuild the title/content search.
    $sku_clause = $wpdb->prepare(
    “EXISTS (
    SELECT 1 FROM {$wpdb->postmeta} product_sku
    WHERE product_sku.meta_key = ‘_sku’
    AND product_sku.meta_value LIKE %s
    AND product_sku.post_id = {$wpdb->posts}.ID
    )
    OR {$wpdb->posts}.ID IN (
    SELECT variation.post_parent
    FROM {$wpdb->posts} variation
    INNER JOIN {$wpdb->postmeta} variation_sku ON variation_sku.post_id = variation.ID
    WHERE variation.post_type = ‘product_variation’
    AND variation.post_status = ‘publish’
    AND variation.post_parent > 0
    AND variation_sku.meta_key = ‘_sku’
    AND variation_sku.meta_value LIKE %s
    )”,
    $like,
    $like
    );

    // CRITICAL: restore the % wildcards so they survive into the final query.
    $sku_clause = $wpdb->remove_placeholder_escape( $sku_clause );

    // MERGE with WordPress’s existing word-split search instead of replacing it:
    // AND ( (core word search) OR (sku / variation-sku match) )
    if ( ” !== trim( (string) $search ) ) {
    $core = preg_replace( ‘/^\s*AND\s+/i’, ”, $search ); // strip leading “AND”
    $search = ” AND ( {$core} OR ( {$sku_clause} ) )”;
    } else {
    $search = ” AND ( {$sku_clause} )”;
    }

    return $search;
    }
    Note this function is currently defined unconditionally (no function_exists guard), so we couldn’t override it from the child theme — we’ve temporarily disabled it via a must-use plugin to keep the live store searchable. Once you deploy the corrected version, tell us and we’ll remove our temporary plugin and re-test (multi-word, apostrophes, and a real variation-SKU lookup). FTP is still active.

    Avatar: Andrew Mitchell
    Andrew Mitchell
    Support staff
    July 17, 2026 at 23:21

    The variation-SKU filter was previously replacing WordPress’s native search clause instead of extending it.

    We have corrected the etheme_search_parent_products_by_variation_sku() function as follows:

    – The original WordPress word-based search is now preserved.
    – SKU and variation-SKU matching have been added as an OR condition.
    – Prepared wildcard placeholders are explicitly restored using remove_placeholder_escape().
    – Apostrophe escaping remains in place.

    We have also removed the previous child-theme workaround, as it could override the corrected core filter.

    Our validation confirmed that:

    – Searching for “Google Nest” correctly returns both “Google Nest Mini” and “Google Nest Audio.”
    – The SQL query includes separate %Google% and`%Nest% conditions.
    – No {hash} placeholders remain in the executed SQL.
    – Apostrophe searches no longer produce SQL errors.
    – Direct SKU searches return the corresponding product.

    The corrected file has now been deployed. Please remove the temporary MU-plugin and re-test the multi-word, apostrophe, and variation-SKU scenarios on your store.

    Best regards,
    8Theme Team

  • Viewing 11 results - 1 through 11 (of 11 total)

You must be logged in to reply to this topic.Log in/Sign up

We're using our own and third-party cookies to improve your experience and our website. Keep on browsing to accept our cookie policy.