Wordpress - Is get_option() faster than accessing get_transient()?
Today I run a test over my db to explore the speed difference between accessing a key from options, custom table & transients. I ran the test for 1000 times and following is the time taken to run 1000 get operations:
Keep in mind that the options table is used for both options and transients on most systems, and that table has been optimised, with indexes added. So it's not a fair comparison
get_transient() 0.0245 seconds get_option() 0.0068 seconds simple select operation from Custom Table 0.65 seconds
This is also an unfair comparison, options with the autoload
option set, will be loaded in advanced in a single query early on. So get_option
is pulling from WP_Cache
, the option has already been retrieved.
TLDR: It's not actually fetching the option, it was already fetched, it's just pulling it from memory due to the autoload
option
I also checked that transient was not expired during this test.
This shouldn't have an impact on a normal system on transient retrieval, after all it doesn't know if it's expired until it's been retrieved.
So the question is, is get_option() faster than get_transient() or did I mess up something in my test?
It depends:
- On most systems, transients are stored using options, both involve a
get_option
call - Options with
autoload
set to true are all loaded in a single call at the start so they're kept in memory, no queries happen after this - Object caching caches both autoloaded options, and transients
Is custom table delay due to options being cached default by WordPress?
Very possible, but how fast that select takes depends a lot on the query and table design
Also, is options also cached by different caching plugins like the transients?
Yes, WP_Cache
is used, which will store it in memory for the rest of the request. Caching plugins might persist these values for performance reasons.
Repeatability
These are all cached via WP_Cache
so the second time you request it, no DB is involved.
Variability and It Depends
This all assumes a common basis, but what about object caches?
Lets introduce a MemcacheD instance, or a Redis instance ( I STRONGLY recommend you do so if you have the option, HUGE performance benefits for well built sites, especially if you use them for page caching, unless you have something like Varnish setup )
Now we have a new situation:
- Now data is stored in RAM, and once it's fetched from the DB it's primed, and access times are dramatically reduced. Still slower than a variable, but significantly faster than a database query
- A lot of new data is stored in
WP_Cache
that normally isn't. E.g.WP_Post
objects, post meta, etc WP_Cache
now persists across requests- MemcacheD etc can eliminate expired transients etc
So now transients and options have the same access cost. They were already close, but they're now negligible and have more to do with the CPU load at the time the request was made.
So For Performance Should I Use Transients or Options?
While it's a worthy question to wonder about, the answer is that the difference is negligible and within the margins of error
So stop micro-optimising, they're the same storage medium, and this is not worthy of your time
- Use options if you need to store something that's site wide
- Use transients to temporarily store things that are expensive to calculate so you don't have to the next time
It is not worth your time to choose one over the other based on performance, there's no meaningful difference.
There are far better things to do to optimise that give significantly greater savings, e.g. using taxonomies instead of meta in post queries, not using __not
style parameters, doing fewer things on the page, installing an object cache, lower posts per page, avoiding remote requests etc
What About A Custom Table That Will...
No, the options table is already well optimised, using a custom table will simply move operations outside of the WP Caching system, forcing you to write your own
If no object caching is found, get_transient
calls get_option
twice, once or the expiry interval and one for the value, therefor it is not going to be faster.
get_option
performance by itself will be impacted on whether the option is "autoloaded" (default) or not. All autoloaded options are retrieved in one request for the DB and stored in the memory cache, and therefor there should be very little impact on how many times you call get_option
even if it is for different options.
When you access the DB directly you bypass all caching and other performance improvements, and it is expected to be slower unless you implement some smart logic by yourself.
All that said, I am not sure your test was a good one, but regardless, the whole discussion is pointless as if you really care about performance you will use object cache system (and the relevant plugin) which will bring data access time much closer to zero.... and of course if you decide to use your own DB tables, you should integrate your access APIs with the object caching mechanism.