0

I have a <form> with about 20 inputs (mostly select and number) which each is an argument in WP_Query if filled.

I learned today that I could use transients to store results which seems like a good opportunity to ease the blow on server, after all: this is rather complicated query.

My plan is:

  • User fills inputs - his/her choice: which, what or if
  • Generate string from filled inputs a.k.a value-1=value&value-2=250000
  • Check if transient with the key of that string already exists
  • If exists - show results from transient
  • If doesn't exist - new WP_Query
  • Set transient with key being that string

I understand that this is a long shot because there are quite a few inputs (especially number inputs - what are the odds, right?) but if I have high traffic, Im sure some patterns will occur.. Especially most popular choises like leaving everything as is, filling only first input etc.


Question:

Would the "extra load" of transient checking and the space required in database outweight the possible resorce gain from transients?

This seems like a very good plan to me but I've been wrong before for few times.. If content is dynamic, I could set transition time for 1 hour for example. Would that work as it does in my head?


  • transient keys can be max 45 characters, you'd maybe have to hash the parameters to generate a key. – Milo Jan 2 '16 at 16:57
2

I have read quite a few of your posts and it seems like your queries are really complex which either slows the page or simply crashes it.

Transients are definitely an option to store the results of such labor intensive queries. As @s_ha_dum mentioned, you'll need to look into what you will be saving.

Would the "extra load" of transient checking and the space required in database outweight the possible resorce gain from transients?

You need to remember that transients are quite expensive to create, so that is something that you would not want to do every hour like you have said. A transient should be created with expiry times that would make them useful, like set the deletion time to something like days or month.

Once created, checking and getting data from a transients simply means 2 db calls in less than 0.002 seconds, so you definitely gain quite a lot on really expensive operations.

Space should never be an issue in the db as you would only want to store post ID's and not the complete object. We want to store as little data in our transient as possible. It is going to mean that you would need to run a second query to get the post objects, but this query will be much leaner. The big score here would be that the first expensive query is dealt with and eliminated. The first query should also be much leaner because we would query id's only.

You can and must in situations where input data is dynamic, use the input data to create a dynamic transient name. You need to remember, a transient's name can only be 45 characters long. A name longer than 45 characters make that the transient is not created, and every page load tries to create a transient. As I said, transients are expensive to create and you do not want to create a transient on every page load as this will add even more load on an already overloaded query. I always pass my input data to md5() (which generate a 32 character key) to create a unique hashed key and then have a transient name like some_name_{md5()_result}. Just remember to convert arrays with json_encode() first and then use that result to pass to md5(). You can look into some of these posts to see examples using md5().

What might be an issue here is the amount of transients you are going to create. If you have a possible 1 million dynamic input combinations, you are going to create 1 million transients which can have effects when you delete the transients. This can again cause an issue with crashing the back end.

If the input is dynamic, you are going to save empty values as well for queries where no posts are returned, so you would need to take that into consideration.

What really is also a big factor here is, what is the possibility of two or ten or hundred users using the same exact input values in a week. I mean, there are no usefulness in creating a transient if only one or two people are ever going to use the same exact input values. As I said, creating transients are expensive, so you would not want to unnecessarily create a transient just for one or two people

At the end of day, you will need to take this info and decide how useful or useless a transient would be and then act on that.

Here is just an idea if you wish to have transients

// 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 );
}

We can then just flush all transients when we publish a new post, deletes it, undelete or update a post

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_%')" );
});
1

what are the odds, right?

The odds make the project pretty pointless, actually.

If you have twenty inputs, each with certainly more than 2 options per input you will very easily get in to the millions of possibilities.

Even at 2 per input you'd need to save a few hundred result sets so you'd have a tremendous number of queries anyway. You can's save the same result set forever (which is implied in the fact you seem to know you need "transients") because you'd missing new posts so you have to have your results expire fairly often which would mean that you'd need new queries to replace them.

Would the "extra load" of transient checking and the space required in database outweight the possible resorce gain from transients?

Given the number of queries that you'd necessarily have to run the transient checking is necessarily going to be unnecessary overhead-- that that will never pay off in any significant way. Likewise with the transient saving. You have, in my opinion, database reads and writes that will virtually never prove useful.

As for the space, you could have hundreds or millions of key/values the database, which in my estimation are going to be virtually useless. On the low end, any typical hosting environment should be able to handle the storage but on the high end you may end up running out of space.

Also, think of how you would save the results. If you save IDs only you still need to run a query to get the rest of the data. If you save the whole query your space requirements go up by orders of magnitude.

The only way I see this working out in your favor is if you have truly staggering volume-- on the order of this site, for example. And I seriously doubt that is going to be the case.

  • You are going to have to explain that, @PieterGoosen. I gave my reasons, at length, as to why I think they will never prove useful-- mainly because the OP is dealing with thousands, if not millions, of patterns. When you consider the number of possibilities and consider that the result sets would have to time out periodically the chances of actually getting to use a result is very very small. – s_ha_dum Jan 3 '16 at 16:20
  • OK, ya, patterns might be a real issue here. Did not take that into account – Pieter Goosen Jan 3 '16 at 16:50
  • And one of the samples is value-2=250000-- so that could potentially be trillions of possibilities all by itself. – s_ha_dum Jan 3 '16 at 16:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.