为什么WordPress' get_results明显慢于phpMyAdmin?

时间:2015-11-20 01:51:11

标签: wordpress

背景/设置

我正在研究通过WordPress构建的Web应用程序,该应用程序根据测试数据跟踪和生成报告。我使用高级自定义字段(ACF)来创建所有测试字段,并将它们存储在WP的默认wp_postmeta表中。这里的主要限制是表的键 - >值对 - ACF"中继器"字段(本质上是一个数组)与密钥一起存储,引用数组名称,位置和任何子数组键都作为一个字符串(例如下面的例子)。

在保存和检索我需要的数据时,ACF刚刚杀死了我的应用程序速度,所以我编写了一些MySQL查询,使用WP的$wpdb->get_results函数将数据直接从数据库中取出。

问题

在WP $wpdb->get_results中运行一个有点复杂的MySQL语句要比通过phpMyAdmin运行它更慢。

查询

SELECT ID as part_id, post_title as part_title,
    GROUP_CONCAT(m2.meta_value ORDER BY m2.meta_key DESC SEPARATOR ', ') as part_name
FROM  `wp_postmeta` m
JOIN wp_posts part      ON part.ID = m.meta_value
JOIN wp_postmeta m2     ON m2.post_id = m.meta_value
WHERE part.ID       = m.meta_value
    AND m2.post_id  = m.meta_value
    AND m.meta_key  LIKE 'participants_%_participant'
    AND m.post_id   = '51911'
    AND post_type   = 'participant'
    AND post_status = 'publish'
    AND (
        m2.meta_key = 'first_name'
        OR m2.meta_key = 'last_name'
    )
GROUP BY ID
ORDER BY post_title

更多详情

在phpMyAdmin中,查询在不到一秒的时间内执行。通过get_results,它超出了我的页面。

我通过在php页面上只运行此查询(以及print_r在结果上运行,但页面超时,我已经消除了所有其他代码问题。)

错误日志已验证正在运行和记录,但未从脚本中记录错误。

wp_postmeta has this structure

作为特定的数据摘录示例:

meta_id | post_id|         meta_key           | meta_value
305361  |  5713  | participants_0_participant | 14444
305362  |  5191  | participants_0_participant | 14445
305363  |  5890  | participants_0_participant | 14446
305364  |  14444 | first_name                 | Joe
/*
  `5191` is the class ID that the test is related to
  `*_0` refers to the participant position in the participants array
  `14444` is the participant unique ID
8/

类和参与者是post_types - 他们都有wp_posts table中的条目。

php.ini包含(通过phpinfo()验证设置)

memory_limit = 2048M
max_execution_time = 1000
set_time_limit = 1000

我知道这个数据库结构远非理想的应用程序(它让我在内部哭了一下)。在未来它将被转换为更合理的设置,但是现在我只是想确定是否存在可以快速修复的难以控制的原因。

2 个答案:

答案 0 :(得分:4)

如果你真的很好奇,你可以take a look

enter image description here

根据您要从查询中返回的内容,该函数将规范化输出并重新格式化。这涉及循环结果并构建新的输出结构,这会导致处理惩罚。

由于您关心的是性能,您可以直接使用query()方法并绕过其他处理:

$results = $wbdp->query("your query goes here");

参考:http://codex.wordpress.org/Class_Reference/wpdb#Running_General_Queries

请注意不要通过此方法引入潜在的SQL注入攻击。

答案 1 :(得分:0)

加速涉及wp_postmeta的所有(?)查询的一种方法是在此处获取建议:

http://mysql.rjweb.org/doc.php/index_cookbook_mysql#speeding_up_wp_postmeta

它讨论了一个更好的模式,特别是改进了索引。