So all you need is simply 1 random post, 1 random post->ID or 1 post link, you dont need to go through all the hoops. (Update: added $wpdb function to tests)

Jump to conclusion or lets evaluate our options here:

query_posts(), get_posts(),wp_query(), $wpdb

As a rule of thumb, usually we can say wp_query > get_posts > query_posts, meaning; you should almost never ever use query_posts. And usually between the two, wp_query. performs better over get_posts in most situations. But, in our case, that’s not the case.

First, lets establish the fact that the end result is the same for all 3 methods; you’ll get 1 random post – object. I used the very same query args for all 3 methods:

		function eo_get_a_post_queryposts(){
			$args = array( 'posts_per_page' => 1, 'orderby' => 'rand' );
			$rand_post = query_posts( $args );
			return $rand_post;
		}
		function eo_get_a_post_getposts(){
			$args = array( 'posts_per_page' => 1, 'orderby' => 'rand' );
			$rand_post = get_posts( $args );
			return $rand_post;
		}
		function eo_get_a_post_wpquery(){
			$args = array( 'posts_per_page' => 1, 'orderby' => 'rand' );
			$rand_post_query_result = new WP_Query( $args );
			$rand_post = $rand_post_query_result->posts[0];
			return $rand_post;
		}
		function eo_get_a_post_wpdb() {
			global $wpdb;
			$rand_post = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE post_status = 'publish' AND post_type = 'post' ORDER BY RAND() LIMIT 1");
			return $rand_post;
		}

And like I said the result you are gonna get is the same:

eogetonepostrand1

 

So, lets get down to the main point, the speed. Like you can imagine, query_posts is off the table, you can see how poorly it does compared to get_posts:

eogetonepostrand2

 

The question was which was slightly better, get_posts or wp_query ? I thought wp_query would do better, like it usually does, since get_posts is essentially a wrapper for wp_query, but to my suprise, get_posts was faster:

eogetonepostrand3

I ran it 10,000 times to make sure – instead of 100. But the result wouldn’t change if you ran it for a mil. time: eogetonepostrand4

Update: I’ve added a $wpdb function to directly query the db, result is the same, get_posts is still faster.

ceClipboard01

Concluison: If all you need is 1 random post (object), simply use get_posts.