改进 SQL 查询 Wordpress 时按 SKU 或名称搜索产品

Improve SQL Query Wordpress when search product by SKU or name

提问人:MechanikGamer 提问时间:10/28/2023 最后编辑:O. JonesMechanikGamer 更新时间:10/28/2023 访问量:69

问:

在 WordPress WooCommerce 管理员中按名称或 SKU 搜索产品时,我遇到了严重的性能问题。对于大约 40k 种产品,搜索需要 16 到 50 秒,这是相当慢的。此外,有时这种延迟会导致 504 错误。

我在网上寻找解决方案,浏览论坛,甚至尝试过像 ChatGPT 这样的聊天机器人,但没有找到明确的解决方案。

使用 Query Monitor 插件,我识别了一个似乎是罪魁祸首的特定查询:

SELECT DISTINCT posts.ID as product_id, posts.post_parent as parent_id
FROM wpprefix_posts posts
LEFT JOIN wpprefix_wc_product_meta_lookup wc_product_meta_lookup
ON posts.ID = wc_product_meta_lookup.product_id
LEFT JOIN wpprefix_wc_product_meta_lookup parent_wc_product_meta_lookup
ON posts.post_type = 'product_variation'
AND parent_wc_product_meta_lookup.product_id = posts.post_parent
WHERE posts.post_type IN ('product','product_variation')
AND ( ( ( posts.post_title LIKE '%DELETEME%')
OR ( posts.post_excerpt LIKE '%DELETEME%')
OR ( posts.post_content LIKE '%DELETEME%' )
OR ( wc_product_meta_lookup.sku LIKE '%DELETEME%' )
OR ( wc_product_meta_lookup.sku = ''
AND parent_wc_product_meta_lookup.sku LIKE '%DELETEME%' ) ))
ORDER BY posts.post_parent ASC, posts.post_title ASC

对于我们的用例,我们只需要根据产品的名称(标题)和 SKU 搜索产品。鉴于我们处理的大量产品,我希望优化此搜索,尤其是在 WooCommerce 管理员中。

此外,我在服务器日志中观察到错误,例如:

upstream timed out unknown error while reading response header from upstream "/wp-admin/edit.php?s=DELETEME..."

我还注意到其他端点(如 GET /wp-json/)的其他一些“从上游读取响应标头时出现未知错误”。

此外,当用户尝试在前端搜索产品时,它依赖于admin-ajax.php,但这也没有按预期运行。

我们在每个产品中都有大量描述,是html代码meybe导致搜索速度变慢?

尽管我的 VPS 设置资源不断增加,但这些问题仍然存在。有人可以指导我如何为我的主题函数 .php 编写或调整代码以提高此搜索查询的性能并解决这些错误吗?任何帮助或指导将不胜感激!

MySQL WordPress 查询优化

评论

0赞 Wilson Hauck 10/28/2023
请提供额外的数据库信息请求。操作系统、版本?RAM大小,#内核,MySQL主机服务器上的任何SSD或NVME设备?在 justpaste.it 上发布 TEXT 数据并分享链接。从您的 SSH 登录根目录,文本结果为:A) SELECT COUNT(*) FROM information_schema.tables;B) 显示全球状态;至少 24 小时后 正常运行时间 C) 显示全局变量;D) 显示完整的流程列表;E) 状态;不是 SHOW STATUS,只是 STATUS;G) 显示引擎 INNODB 状态;用于服务器工作负载调优分析,以提供更长的超时容限建议。
0赞 Rick James 11/9/2023
一个地方说;另一个地方说“posts.post_type IN('产品','product_variation')'——这是哪个?posts.post_type = 'product_variation'
0赞 Rick James 11/9/2023
你能搬到一个地方吗? 是性能杀手。DELETEMEOR
0赞 Rick James 11/9/2023
请提供所涉表格。SHOW CREATE TABLE

答:

0赞 user2314737 10/28/2023 #1

带有运算符的倍数可能会降低查询的性能,尤其是在列具有长文本内容的情况下。LIKEOR

AND 
( 
(posts.post_title LIKE '%DELETEME%')
OR (posts.post_excerpt LIKE '%DELETEME%')
OR (posts.post_content LIKE '%DELETEME%')
OR (wc_product_meta_lookup.sku LIKE '%DELETEME%')
OR (wc_product_meta_lookup.sku = ''
AND parent_wc_product_meta_lookup.sku LIKE '%DELETEME%') 
)

假设您的数据库是 MySQL,您可以在表上使用如下索引:FULLTEXTwpprefix_posts

FULLTEXT (post_title, post_excerpt, post_content)

然后使用该函数

MATCH (post_title, post_excerpt, post_content)

用于搜索代替 s 和 s。%LIKEOR

(请参阅自然语言全文搜索)

桌子也一样.wpprefix_wc_product_meta_lookup

如果有帮助,请告诉我们!

0赞 Freddie Ole saruni 10/28/2023 #2

选择“非重复 p.ID 为product_id”,p.post_parent“为parent_id 从 wpprefix_posts p 左联接wpprefix_wc_product_meta_lookup sku_lookup p.ID = sku_lookup.product_id WHERE p.post_type IN ('产品', 'product_variation') 和 ( p.post_title类似于“%DELETEME%” 或者sku_lookup.sku 类似 '%DELETEME%' ) 按 p.post_parent ASC、p.post_title ASC 订购;

您能否尝试使用 OR 运算符组合搜索产品名称 (post_title) 和 SKU (SKU) 的条件, 我还维护了 DISTINCT 关键字,以确保仅返回唯一的产品 ID。 并保留 ORDER BY 子句以对结果进行排序

0赞 O. Jones 10/28/2023 #3

核心WordPress中的搜索功能使用了臭名昭著的数据库性能反模式。some_content_column LIKE '%searchterm%'

再多的MySQL / MariaDB调整或服务器资源添加也无法解决此问题。这是由核心WordPress对搜索算法的选择引起的。

尝试使用搜索插件来更改算法。我使用 relevanssi 取得了很好的成功。还有其他几个。

(在 postgresql 中,可以设置索引来加速这些 LIKE 搜索,但 WordPress 不支持该数据库。