I have 25000+ products available in WooCommerce.
I am querying my products with the CUSTOM MYSQL query because I want minimal data to fetch instead of getting the whole products in an object.
The Query is working fine and it is as below:
SELECT
p.ID,
m1.meta_value as 'cut',
m2.meta_value as 'polish',
m3.meta_value as 'symmetry',
m4.meta_value as 'fluor_intensity',
m5.meta_value as 'short_name',
m6.meta_value as 'total_sales_price',
m7.meta_value as 'available',
m8.meta_value as 'lab',
m9.meta_value as 'shape',
m10.meta_value as 'size',
m11.meta_value as 'color',
m12.meta_value as 'clarity',
m13.meta_value as 'depth_percent',
m14.meta_value as 'table_percent',
m15.meta_value as 'meas_length',
m16.meta_value as 'meas_width',
m17.meta_value as 'meas_depth',
m18.meta_value as 'price_per_caret',
m19.meta_value as 'fancy_color',
m20.meta_value as 'fancy_intensity',
m21.meta_value as 'image',
m22.meta_value as 'meas_ratio',
m23.meta_value as 'treatment',
m24.meta_value as 'culet_size'
FROM
wp_u8gwgg_posts p
LEFT JOIN wp_u8gwgg_postmeta m1 ON p.id = m1.post_id AND m1.meta_key = '_diamond_cut'
LEFT JOIN wp_u8gwgg_postmeta m2 ON p.id = m2.post_id AND m2.meta_key = '_diamond_polish'
LEFT JOIN wp_u8gwgg_postmeta m3 ON p.id = m3.post_id AND m3.meta_key = '_diamond_symmetry'
LEFT JOIN wp_u8gwgg_postmeta m4 ON p.id = m4.post_id AND m4.meta_key = '_diamond_fluor_intensity'
LEFT JOIN wp_u8gwgg_postmeta m5 ON p.id = m5.post_id AND m5.meta_key = '_diamond_shortname'
LEFT JOIN wp_u8gwgg_postmeta m6 ON p.id = m6.post_id AND m6.meta_key = '_price'
LEFT JOIN wp_u8gwgg_postmeta m7 ON p.id = m7.post_id AND m7.meta_key = '_diamond_available'
LEFT JOIN wp_u8gwgg_postmeta m8 ON p.id = m8.post_id AND m8.meta_key = '_diamond_lab'
LEFT JOIN wp_u8gwgg_postmeta m9 ON p.id = m9.post_id AND m9.meta_key = '_diamond_shape'
LEFT JOIN wp_u8gwgg_postmeta m10 ON p.id = m10.post_id AND m10.meta_key = '_diamond_size'
LEFT JOIN wp_u8gwgg_postmeta m11 ON p.id = m11.post_id AND m11.meta_key = '_diamond_color'
LEFT JOIN wp_u8gwgg_postmeta m12 ON p.id = m12.post_id AND m12.meta_key = '_diamond_clarity'
LEFT JOIN wp_u8gwgg_postmeta m13 ON p.id = m13.post_id AND m13.meta_key = '_diamond_depth_percent'
LEFT JOIN wp_u8gwgg_postmeta m14 ON p.id = m14.post_id AND m14.meta_key = '_diamond_table_percent'
LEFT JOIN wp_u8gwgg_postmeta m15 ON p.id = m15.post_id AND m15.meta_key = '_diamond_meas_length'
LEFT JOIN wp_u8gwgg_postmeta m16 ON p.id = m16.post_id AND m16.meta_key = '_diamond_meas_width'
LEFT JOIN wp_u8gwgg_postmeta m17 ON p.id = m17.post_id AND m17.meta_key = '_diamond_meas_depth'
LEFT JOIN wp_u8gwgg_postmeta m18 ON p.id = m18.post_id AND m18.meta_key = '_diamond_price_per_carat'
LEFT JOIN wp_u8gwgg_postmeta m19 ON p.id = m19.post_id AND m19.meta_key = '_diamond_fancy_color'
LEFT JOIN wp_u8gwgg_postmeta m20 ON p.id = m20.post_id AND m20.meta_key = '_diamond_fancy_intensity'
LEFT JOIN wp_u8gwgg_postmeta m21 ON p.id = m21.post_id AND m21.meta_key = '_knawatfibu_url'
LEFT JOIN wp_u8gwgg_postmeta m22 ON p.id = m22.post_id AND m22.meta_key = '_diamond_meas_ratio'
LEFT JOIN wp_u8gwgg_postmeta m23 ON p.id = m23.post_id AND m23.meta_key = '_diamond_treatment'
LEFT JOIN wp_u8gwgg_postmeta m24 ON p.id = m24.post_id AND m24.meta_key = '_diamond_culet_size'
WHERE p.post_type = "product"
ORDER BY total_sales_price+0 ASC
LIMIT 0, 12
The real struggle occurs when I am adding, ORDER BY total_sales_price+0 ASC
in my query.
So, when I am not adding the ORDER BY
clause, the query is giving me results in around 0.02s
And the same query with ORDER BY
is giving me results in around 9.4s
Questions:
- How can I just decrease the fetching records time with
ORDER BY
clause? - Is there any way by which this query can perform better for end-users?
Thanks in Advance.
3
Answers
Finally, I have implemented the Lookup table concept from WooCommerce.
You can check the doc here: https://developer.woocommerce.com/2019/04/01/performance-improvements-in-3-6/
My search timing before was
15-20 seconds
before applying the lookup table. And now it down to1.5-3 seconds
I just needed to change the query to:
Left Joins are
GONE
now and all data I can Look it under 1 table.If anyone is looking for the same, can implement the Lookup table for speed optimization.
You can filter wp_u8gwgg_posts and price first by using a sub-query and filtering the number of sorted rows. Then only left join the rest. That should limit the number of rows you need to join.
Two speedups:
A solution to some WP (or Woo) performance issues: http://mysql.rjweb.org/doc.php/index_cookbook_mysql#speeding_up_wp_postmeta — This will speed up much of WP and WooCommerce, especially for a 24-way
JOIN
like you have.Find the rows first, then do all those joins.
Here’s what I mean by the first suggestion:
First, let’s find the 12 items you want:
Note that I used
JOIN
, notLEFT JOIN
. Don’t useLEFT
unless the ‘right’ table is really optional. Having the improved index as mentioned in the link above will help even this query.Next, use that as a subquery to do the rest of the work:
It would be much better if
price
were a numeric column in theposts
table, but that violates the generality of WP and Woo, wherein the value(s) you want to filter on or order by are not easily accessible.