带有动态WP_QUERY的瞬变

时间:2016-01-02 作者:N00b

我有一个<form> 大约有20个输入(大部分selectnumber) 每个都是WP_Query 如果已填充。

今天我了解到,我可以使用瞬态来存储结果,这似乎是一个很好的机会来减轻对服务器的打击,毕竟:这是一个相当复杂的查询。

我的计划是:

用户填充输入-他/她的选择:哪个、什么或如果从填充的输入生成字符串value-1=value&value-2=250000string 已存在(如果存在)-显示瞬态结果(如果不存在)-新建WP_Querystring我知道这是一个长期目标,因为inputs (尤其是数字inputs - 可能性有多大,对吗?)但是如果我的流量很大,我肯定会出现一些模式。。尤其是最受欢迎的选择,如保持一切原样,只先填充input

<小时>Question:

瞬态检查的“额外负载”和数据库中所需的空间是否会超过瞬态可能带来的资源收益?

对我来说,这似乎是一个很好的计划,但我之前已经错了好几次了。。如果内容是动态的,例如,我可以将转换时间设置为1小时。这会像我脑子里想的那样管用吗?

<小时>

2 个回复
最合适的回答,由SO网友:Pieter Goosen 整理而成

我读过你的很多帖子,你的查询似乎非常复杂,要么会减慢页面速度,要么会导致页面崩溃。

瞬态绝对是存储此类劳动密集型查询结果的一种选择。正如@s\\u ha\\u dum所提到的,您需要研究您将要保存的内容。

瞬态检查的“额外负载”和数据库中所需的空间是否会超过瞬态可能带来的资源收益?

您需要记住,创建瞬变非常昂贵,因此这是您不希望像您所说的那样每小时都要做的事情。应创建一个具有到期时间的瞬态,使其有用,例如将删除时间设置为天或月。

一旦创建,从瞬态中检查和获取数据就意味着在不到0.002秒的时间内进行2次db调用,因此在真正昂贵的操作中,您肯定会收获很多。

在db中,空间永远不应该是一个问题,因为您只想存储帖子ID,而不想存储完整的对象。我们希望在瞬态中存储尽可能少的数据。这意味着您需要运行第二个查询来获取post对象,但此查询将更加精简。这里最重要的一点是处理并消除了第一个昂贵的查询。第一个查询也应该更加精简,因为我们将只查询id。

在输入数据是动态的情况下,可以而且必须使用输入数据创建动态瞬态名称。你需要记住,一个过渡者的名字只能有45个字符长。超过45个字符的名称使瞬态不会创建,并且每次页面加载都会尝试创建一个瞬态。正如我所说,创建瞬态非常昂贵,您不希望在每个页面负载上创建瞬态,因为这将在已经过载的查询上增加更多负载。我总是将输入数据传递给md5()生成一个32字符的密钥)来创建一个唯一的哈希密钥,然后有一个临时名称,如some_name_{md5()_result}. 只需记住使用json_encode() 首先,然后使用该结果传递给md5(). 你可以调查一下these posts 要查看示例,请使用md5().

这里可能存在的问题是您将要创建的瞬变量。如果可能有100万个动态输入组合,则将创建100万个瞬态,当删除瞬态时,这些瞬态可能会产生影响。这可能再次导致后端崩溃问题。

如果输入是动态的,您还需要为没有返回帖子的查询保存空值,因此您需要考虑这一点。

这里真正的一个重要因素是,两个、十个或一百个用户在一周内使用相同的精确输入值的可能性有多大。我的意思是,如果只有一到两个人会使用相同的精确输入值,那么创建瞬态是没有用的。正如我所说,创建瞬变是昂贵的,所以您不会希望只为一个或两个人创建不必要的瞬变

在一天结束时,你需要掌握这些信息,并决定一个过渡期的有用或无用程度,然后采取行动。

如果你希望有短暂的

// Here is your string of inputs
$args = \'value-1=value&value-2=250000\';
// Create a unique hashed key from the arguments
$key = md5( $args );
//$key = md5( json_encode( $args ) ); // If $args is an array
// Set the transient name
$transient_name = \'custom_input_\' . $key;

if ( false === ( $query = get_transient( $transient_name ) ) ) {
    $query = get_posts( $args . \'&fields=ids\' ) // Only get post ids. Alter if $args is an array

    // Set the transient only if we have results
    if ( $query )
        set_transient( 
            $transient_name, // Transient name
            $query, // What should be saved
            7 * DAY_IN_SECONDS // Lifespan of transient is 7 days
        );
}

// Now run the second query to get the full objects. Just add \'post_type\' if this is not \'post\' posts
if ( $query ) {
    $args = [
        \'post__in\'       => $query,
        \'posts_per_page\' => count( $query ),
        \'order\'          => \'ASC\',
        \'orderby\'        => \'post_in\'
    ];
    $q = new WP_Query( $args );
    var_dump( $q );
}
然后,我们可以在发布新帖子、删除帖子、取消删除或更新帖子时刷新所有瞬态

add_action( \'transition_post_status\', function ()
{
    global $wpdb;
    $wpdb->query( "DELETE FROM $wpdb->options WHERE `option_name` LIKE (\'_transient%_custom_input_%\')" );
    $wpdb->query( "DELETE FROM $wpdb->options WHERE `option_name` LIKE (\'_transient_timeout%_custom_input_%\')" );
});

SO网友:s_ha_dum

可能性有多大,对吧?

事实上,这种可能性使得这个项目毫无意义。

如果你有20个输入,每个输入肯定有2个以上的选项,那么你将很容易获得数百万种可能性。

即使每个输入2个,您也需要保存几百个结果集,这样无论如何都会有大量的查询。你不能永远保存同一个结果集(这意味着你似乎知道你需要“过渡”),因为你丢失了新的帖子,所以你必须经常让结果过期,这意味着你需要新的查询来替换它们。

瞬态检查的“额外负载”和数据库中所需的空间是否会超过瞬态可能带来的资源收益?

考虑到您必须运行的查询数量,临时检查必然是不必要的开销——这永远不会有任何显著的回报。瞬态保存也是如此。在我看来,数据库读写实际上永远不会有用。

至于空间,数据库中可能有数百或数百万个键/值,据我估计,这些键/值实际上是无用的。在低端,任何典型的托管环境都应该能够处理存储,但在高端,最终可能会耗尽空间。

此外,请考虑如何保存结果。如果只保存ID,则仍需要运行查询以获取其余数据。如果保存整个查询,您的空间需求将增加几个数量级。

我认为这对您有利的唯一方式是,您的数量是否真的惊人——例如,在本网站的顺序上。我严重怀疑情况是否会如此。

相关推荐

Set transient name

我正在使用wordpress REST api从网站向应用服务器提供某些数据。此自定义路由用于发送默认图像,一切正常。现在我想使用set\\u transient,我使用了以下代码来实现。 $transient=\'apidata_json_cache\'; $expiration =2*60; // 2 Minutes if(false === ($feed=get_transient($transient))) { echo \'