大型日历网站的高级元查询(12k+帖子)(175k+wp_postmeta行)

时间:2015-01-17 作者:jostrander

问题是,在我创建的网站上,我选择使用自定义字段而不是日历插件来在“日历”中组织我的帖子。起初,这似乎是实现我所需要的最合乎逻辑的方式。然而,由于导入了所有的内容,结果并不像我预期的那样。我的“日”视图需要2-4秒才能加载约60-100个项目,而“月”视图需要15-22秒才能加载约900个项目。

每个帖子都有一个event_date 存储为的字段YYYYmmdd. 有些帖子可以像普通日历事件一样,在固定或无限的基础上重复。我为此设置了两个字段,一个叫做repeat 具有选项foreveruntil. 此外,还有一个字段,用于显示重复的时间间隔how_often. 其值为Daily, Monthly, Weekly, 和Yearly. 最后但并非最不重要的是,一些帖子有end_date 指定事件的结束。

一些基于另一种分类法的帖子可以说是“自动重复”的,并且每年都会重复出现。

获取此数据并对其进行筛选的最简单方法是使用以下meta\\u查询:

<?php
$mq = [\'meta_query\' =>
        [
        \'relation\' => \'OR\',
            [
                \'key\' => \'event_date\',
                \'value\' => $date->format(\'md\'),
                \'compare\' => \'LIKE\',
                \'type\' => \'numeric\'
            ],
            [
                 \'key\' => \'how_often\',
                 \'value\' => array(\'Daily\', \'Monthly\', \'Weekly\'),
                 \'compare\' => \'IN\'
            ]
        ]
    ]
它对当前查询的日期的月份和日期以及其他日期或所有经常性帖子执行类似操作。

然后使用一个函数(省略)测试每个帖子,看看它是否在当天有效。然后将数据传递到视图,以显示给用户。

我不习惯处理EAV表或WordPress,一般来说,当涉及到构建这样的定制内容时。我更愿意使用自定义表构建所有内容,但我担心这将很难用WordPress实现,并且会限制将来的扩展。

问题:我还可以对查询做些什么,尽可能少的工作来消除PHP中由于我的查询太宽而被查询的“额外”帖子

1 个回复
最合适的回答,由SO网友:TheDeadMedic 整理而成

我还可以对查询做些什么,以尽可能少的工作来消除PHP中由于我的查询太宽而被查询的“额外”帖子。

问题是,meta queries are slow. 元数据是一个简单的键=>值类型数据库。键被索引,值被longtext. 就是这样。没有数据类型。无其他索引。没有什么更不用说每一条“规则”都会让你JOIN.

它们可以用于简单的过滤器/开关/比较,但越复杂,就越有可能需要使用其他东西。

对于月视图,我只显示帖子类别、event\\u日期、标题和每天的帖子总数。是否可以仅查询此数据以加快查询速度?

如果可以将存储的日期格式更改为MySQL的默认格式(YYYY-MM-DD), 然后,您可以使用元查询的强制转换功能进行日期比较:

array(
    \'key\'     => \'event_date\',
    \'type\'    => \'DATE\',
    \'compare\' => \'BETWEEN\',
    \'value\'   =>  array(
        date( \'Y-m-01\', $time = current_time( \'timestamp\' ) ),
        date( \'Y-m-t\', $time ), // Last day of current month
    ),
),
这可能会起到提振作用,但不能保证。

如果所有这些都失败了,那么在WordPress中处理此类数据的更好方法是什么?我宁愿远离日历插件,以某种方式使用“帖子”。

毫无疑问,另一张桌子。主索引将是post ID,然后是存储任意事件数据的后续列。我不是db模式的天才,您最好在另一个StackExchange上针对您的问题寻求建议。

钩住save_post 用于更新表,并使用posts_clauses 在中找到WP_Query::get_posts() 要实现联接和自定义查询,请执行以下操作:

function wpse_175152_posts_clauses( $clauses, $wp_query ) {
    $clauses[ \'where\' ];
    $clauses[ \'groupby\' ];
    $clauses[ \'join\' ];
    $clauses[ \'orderby\' ];
    $clauses[ \'distinct\' ];
    $clauses[ \'fields\' ];
    $clauses[ \'limits\' ];

    return $clauses;
}

add_filter( \'posts_clauses\', \'wpse_175152_posts_clauses\', 10, 2 );

结束