【问题标题】:Woocommerce Performance IssuesWoocommerce 性能问题
【发布时间】:2021-11-27 01:22:57
【问题描述】:

想知道是否有人可以就我们在使用 Woocommerce 网站时遇到的一些性能问题提供一些新的观点。

该站点是位于 Digital Ocean 液滴上的单个应用程序和数据库 - 该盒子被指定为 16 核 / 32 GB RAM / 200GB 磁盘。

在最近几个月中,我们看到在所采取的服务器操作上出现了一些零星的表现:

  • 已安装 MySQLTuner.pl 并对 MySQL 配置进行了建议的更改
  • 已启用 MySQL 慢速日志记录
  • 索引应用于慢查询日志中标识的查询

性能稳定下来,但几个月后,我们开始在繁忙时间再次体验到性能峰值(大约每小时 300 个独立访问者)​服务器 CPU 处于 100% 并且服务器变得无响应 - 这可能会持续目前几分钟。

最近几天我们实施了:

  • Cloudflare 代理所有流量
  • 已应用所有速度优化
  • 已安装并启动并运行 Wordpress 的自动平台优化
  • 已安装查询监视器
  • 查询监视器仅识别出 1 个执行时间为 0.8 秒的慢查询
  • 将 WP 内存限制从 40MB 增加到 256MB

回顾 MySQL 慢日志,我可以看到下面的查询,使用 EXPLAIN 语法,看起来所有表都已编入索引,但是由于其编译方式,我不确定它是否可以进一步优化或实际上 从哪里追溯正在运行的查询 - 这不会出现在 Query Monitor 慢速日志中。

    Count: 1546  Time=20.98s (32437s)  Lock=3.03s (4679s)  Rows_sent=249.1 (385062), Rows_examined=2654.6 (4104056), Rows_affected=0.0 (0), user@localhost
      SELECT DISTINCT wp_posts.ID FROM wp_posts INNER JOIN (
      SELECT DISTINCT post_id FROM wp_postmeta 
      WHERE post_id NOT IN (SELECT post_id FROM wp_postmeta WHERE meta_key = 'S')
      AND post_id NOT IN(SELECT DISTINCT tr.object_id FROM wp_termmeta 
      INNER JOIN wp_term_taxonomy tt on wp_termmeta.term_id = tt.term_id
      INNER JOIN wp_term_relationships tr on tt.term_taxonomy_id = tr.term_taxonomy_id
      WHERE tt.taxonomy = 'S' AND meta_key='S')
      UNION ALL
      SELECT  post_id FROM wp_postmeta 
      WHERE (meta_key = 'S' AND meta_value = 'S') OR (meta_key = 'S' AND meta_value IN ('S'))
      UNION ALL 
      SELECT  tr.object_id FROM wp_termmeta 
      INNER JOIN wp_term_taxonomy tt on wp_termmeta.term_id = tt.term_id
      INNER JOIN wp_term_relationships tr on tt.term_taxonomy_id = tr.term_taxonomy_id
      WHERE tt.taxonomy = 'S' 
      AND ( (meta_key='S' AND meta_value='S') OR (meta_key = 'S' AND meta_value IN ('S')) )
      AND tr.object_id NOT IN (SELECT DISTINCT post_id FROM wp_postmeta WHERE meta_key = 'S')
      ) as rfilter on wp_posts.ID = rfilter.post_id WHERE post_type = 'S'

理想情况下,我想在进一步研究数据库集群和负载平衡流量之前找到解决此问题的方法。

任何帮助将不胜感激。

【问题讨论】:

    标签: mysql wordpress woocommerce


    【解决方案1】:

    感谢您提供慢速日志摘要。

    这个插件将有助于许多 postmeta 的使用: https://wordpress.org/plugins/index-wp-mysql-for-speed/

    为了进一步挖掘,让我从重新格式化查询开始:

    SELECT  DISTINCT wp_posts.ID
        FROM  wp_posts
        INNER JOIN  
          (
            SELECT  DISTINCT post_id
                FROM  wp_postmeta
                WHERE  post_id NOT IN (
                    SELECT  post_id
                        FROM  wp_postmeta
                        WHERE  meta_key = 'S'
                              )
                  AND  post_id NOT IN (
                    SELECT  DISTINCT tr.object_id
                        FROM  wp_termmeta
                        INNER JOIN  wp_term_taxonomy tt  
                               ON wp_termmeta.term_id = tt.term_id
                        INNER JOIN  wp_term_relationships tr
                               ON tt.term_taxonomy_id = tr.term_taxonomy_id
                        WHERE  tt.taxonomy = 'S'
                          AND  meta_key='S'
                              )
            UNION  ALL 
            SELECT  post_id
                FROM  wp_postmeta
                WHERE  (meta_key = 'S' AND  meta_value = 'S' )
                   OR  (meta_key = 'S' AND  meta_value IN ('S') )
            UNION  ALL 
            SELECT  tr.object_id
                FROM  wp_termmeta
                INNER JOIN  wp_term_taxonomy tt 
                       ON wp_termmeta.term_id = tt.term_id
                INNER JOIN  wp_term_relationships tr 
                       ON tt.term_taxonomy_id = tr.term_taxonomy_id
                WHERE  tt.taxonomy = 'S'
                  AND  ( (meta_key='S  AND  meta_value='S')
                     OR  (meta_key = 'S' AND  meta_value IN ('S')) 
                       )
                  AND  tr.object_id NOT IN (
                    SELECT  DISTINCT post_id
                        FROM  wp_postmeta
                        WHERE  meta_key = 'S') 
          ) as rfilter  ON wp_posts.ID = rfilter.post_id
        WHERE  post_type = 'S'
    

    让我来看看我能看到什么......

    • DISTINCT 通常需要传递数据。如果在去重之前只有几行,那么这不是问题。 4 个DISTINCTs 中的一些可能是多余的。
    • IN (SELECT ...) -- 这种结构通常效率低下。 NOT IN .. 通常更糟。很难预测改进它的最佳方法。 NOT EXISTS ( SELECT 1 ... )LEFT JOIN .. IS NULL 是可能的候选人。
    • 该插件将向 wp_metadata 添加一些索引以提供帮助。
    • OR -- 通常它禁止使用索引。在此查询的两种用法中,似乎都没有必要。清理它会让插件完成它的工作。
    • (我可能没有发现所有内容,因为并非所有列都由表名或别名限定。)
    • meta_value = 'S'meta_value IN ('S') 的处理方式相同。

    一个例子:

    post_id NOT IN ( SELECT  post_id
                    FROM  wp_postmeta
                    WHERE  meta_key = 'S' )   
    

    -->

    NOT EXISTS( SELECT 1
                    FROM  wp_postmeta
                    WHERE  meta_key = 'S'
                      AND  post_id = wp_posts.post_id )   
    

    插件会为该子查询添加最佳索引。

    【讨论】:

    • 谢谢 Rick - 我刚刚回来重新格式化并查看 SQL - 非常感谢那里有很多考虑
    猜你喜欢
    • 2017-04-13
    • 2022-01-04
    • 2014-03-31
    • 1970-01-01
    • 2010-09-05
    • 2012-09-25
    • 2015-05-28
    • 2015-06-20
    相关资源
    最近更新 更多