Tonight I read an article on WPTuts+ titled 10 Quick Tips: Optimizing & Speeding Up Your WordPress Site. For the most part it’s a good article with lots of great tips, but there is one tip which is just plain incorrect:
Using a constant instead of get_option('home');
saves a database call.
I left a comment there (still in moderation) and normally I would have moved on. However, this is not the first time I’ve read articles which mistakenly promise a performance gain from this tip. If I had a dollar for everytime I’ve read an article saying to not use get_option
, I’d have.. well probably only the better part of 50 dollars, but that’s still way too much!
I felt I had to write this article to debunk the myth.
Note, I’m not the first person to write about this. This myth has been debunked by people far cleverer than me, but I can’t quickly find where now (I have a feeling it may have been Ozh though).
The tip in question is number 3, “Declare a Constant for Most Used WordPress Database Values”, which states (bold mine):
This can be useful for the theme developer to reduce the number of database query on database. As a being WordPress theme developer we need to use some WordPress function which we need to use most frequently and more than once in a page.
For example, to get the url of the home page we generally use the
get_option('home');
. This function actually perform the query on database and get the value we want. As we know this will be same for all cases and we might need this value on various places.
The author goes on to propose creating a constant in the wp-config.php file, then finishes with:
After declaring this constant you need to use this constant instead of the
get_option('home')
or similar function. So this will reduce the number query in the page. You can define constants for template directory too.
Leaving aside the fact that you could use the home_url or site_url functions instead of get_option('home')
, it’s just plain wrong to state that it uses a database call.
The home option, and many others, are autoloaded on each page load. It doesn’t matter whether you use the option or not, WordPress gets it from the database (if the autoload column is set to yes). Take a look at the following screenshot of the options table in my development instance of WordPress, noting that the autoload column is set to yes for home:
For anyone who’s interested in what happens and the code behind this, check out the wp_load_alloptions function. You’ll see it effectively does one database call to load all the options where autoload equals yes.
As a result, the home option is loaded on every page load whether you use get_option('home')
or not. When you do use get_option('home')
, it doesn’t access the database, it simply gets the home value from the already loaded array of options. No performance gain!
For those about to argue that using an array variable may be slightly slower than using a CONSTANT, check out the answers to this question on Stack Exchange, which range from the difference being too small to worry about, to no gain, to it actually being slower. Bet yet, check out Ozh’s 2006 post where he finds variables are faster than constants.
So, this technique does not save a database call. Most of the template tags that you might use relating to the path of the site etc, are autoloaded, including the template directory and blog name.
Also, note that all options added by plugins are autoloaded, unless the plugin authors have specifically said not to autoload them. I used to do things like load my plugin’s options into a global variable and access it that way instead of using get_option
, which I mistakenly thought was hitting the database.
I don’t blame the author of the article. This is a myth that perpetuates because so many people have written about it before. I actually used to do this way back in 2007 and although I never wrote a post about it, I’m sure I left comments around about what a great technique it was! I was quite surprised when I learnt the truth in about 2009.
Nicely done, Stephen! Really appreciate you taking the time to write this up.
I’ll see if I can’t get the article amended ASAP. We don’t want to be helping perpetuate a myth! 🙂
Thanks Japh,
It’s just one of those things that makes sense to people, so it keeps on running. Like I said, I used to believe it wholeheartedly too! But if we can just make people aware of the way it actually works, the world will be just a slightly better place. 🙂
I think constants may be faster or slower than vars, depending on the build & version & a few things
Anyway, tutplus is probably the most unreliable source about WP. They suck, period 🙂
Hi Ozh,
Thanks for the comment.
If you did write about this topic before, let me know and I’ll link to it (I couldn’t find it, but I think you did).
As for WPTuts+, I rarely read their articles, but when I do they generally have some value (I wouldn’t go as far as saying they suck). 🙂
That said, I’m not a fan of the large scale, mass traffic, publishing models which have taken over pretty much all niches, with list posts, regurgitated content and sites such as this taking over from smaller sites run by individuals reporting on the stuff they’ve discovered personally.
Hmm, nostalgia for the old days…
This is really helpful. But say, the function the_permalink is called three times on the index.php file. Would it really reduce the database calls if I assign it to a variable? Please reply.
Stephen,
Thanks for this helpful post. You quote the WPTuts+ article as saying, “You can define constants for template directory too.” I often read similar advice to reduce the number of database calls by defining constants in wp-config.php to be used in place of get_bloginfo(‘stylesheet_directory’) or get_bloginfo(‘theme_directory’). It sounds like this advice may be wrong for the very same reason you give above — these functions merely pull information from the options table that is already loaded anyway. Is there any way you can you confirm this? When I look at the code for get_bloginfo(), it does appear that hundreds of lines of PHP are involved just to get a simple, commonly-used string. Even if there were no database call, I wonder about other inefficiencies. Thanks for any thoughts you have on this.