Index: wp-includes/post.php
===================================================================
--- wp-includes/post.php	(revision 19788)
+++ wp-includes/post.php	(working copy)
@@ -5320,3 +5320,23 @@
 		wp_update_term_count( $tt_ids, $taxonomy );
 	}
 }
+
+/**
+ * Adds any posts from the given ids to the cache that do not already exist in cache
+ * 
+ * @since 3.4.0
+ * 
+ * @access private
+ * @param array $post_ids ID list
+ * @param bool $update_term_cache Whether to update the term cache. Default is true.
+ * @param bool $update_meta_cache Whether to update the meta cache. Default is true.
+ */
+function _prime_post_caches( $ids, $update_term_cache = true, $update_meta_cache = true ) {
+	global $wpdb;
+	
+	$non_cached_ids = _get_non_cached_ids( $ids, 'posts' );
+	if ( !empty( $non_cached_ids ) ) {
+		$fresh_posts = $wpdb->get_results( sprintf( "SELECT $wpdb->posts.* FROM $wpdb->posts WHERE ID IN (%s)", join( ",", $non_cached_ids ) ) );
+		update_post_caches( $fresh_posts, 'any', $update_term_cache, $update_meta_cache );
+	}
+}
\ No newline at end of file
Index: wp-includes/functions.php
===================================================================
--- wp-includes/functions.php	(revision 19788)
+++ wp-includes/functions.php	(working copy)
@@ -3699,3 +3699,26 @@
 	else
 		return $caller;
 }
+
+/**
+ * Retrieve ids that are not already present in the cache
+ *
+ * @since 3.4.0
+ *
+ * @param array $object_ids ID list
+ * @param string $cache_key The cache bucket to check against
+ *
+ * @return array
+ */
+function _get_non_cached_ids( $object_ids, $cache_key ) {
+	$clean = array();
+	foreach ( $object_ids as $id ) {
+		$id = (int) $id;
+		if ( !wp_cache_get( $id, $cache_key ) ) {
+			$clean[] = $id;
+		}
+	}
+
+	return $clean;
+}
+
Index: wp-includes/query.php
===================================================================
--- wp-includes/query.php	(revision 19788)
+++ wp-includes/query.php	(working copy)
@@ -1951,6 +1951,7 @@
 		$fields = '';
 		$post_status_join = false;
 		$page = 1;
+		$expand_ids = false;
 
 		if ( isset( $q['caller_get_posts'] ) ) {
 			_deprecated_argument( 'WP_Query', '3.1', __( '"caller_get_posts" is deprecated. Use "ignore_sticky_posts" instead.' ) );
@@ -2597,6 +2598,11 @@
 				$$piece = isset( $clauses[ $piece ] ) ? $clauses[ $piece ] : '';
 		}
 
+		if ( "$wpdb->posts.*" == $fields ) {
+			$fields = "$wpdb->posts.ID";
+			$expand_ids = true;
+		}
+
 		if ( ! empty($groupby) )
 			$groupby = 'GROUP BY ' . $groupby;
 		if ( !empty( $orderby ) )
@@ -2626,8 +2632,24 @@
 			return $r;
 		}
 
-		$this->posts = $wpdb->get_results($this->request);
+		if ( $expand_ids ) {
+			$ids = $wpdb->get_col( $this->request );
 
+			if ( $ids ) {
+				$this->set_found_posts( $q, $limits );
+
+				_prime_post_caches($ids, $q['update_post_term_cache'], $q['update_post_meta_cache']);
+
+				$this->posts = array_map( 'get_post', $ids );
+			} else {
+				$this->found_posts = $this->max_num_pages = 0;
+				$this->posts = array();
+			}
+		} else {
+			$this->posts = $wpdb->get_results( $this->request );
+			$this->set_found_posts( $q, $limits );
+		}
+
 		// Raw results filter. Prior to status checks.
 		if ( !$q['suppress_filters'] )
 			$this->posts = apply_filters_ref_array('posts_results', array( $this->posts, &$this ) );
@@ -2645,13 +2667,6 @@
 			$this->comment_count = count($this->comments);
 		}
 
-		if ( !$q['no_found_rows'] && !empty($limits) ) {
-			$found_posts_query = apply_filters_ref_array( 'found_posts_query', array( 'SELECT FOUND_ROWS()', &$this ) );
-			$this->found_posts = $wpdb->get_var( $found_posts_query );
-			$this->found_posts = apply_filters_ref_array( 'found_posts', array( $this->found_posts, &$this ) );
-			$this->max_num_pages = ceil($this->found_posts / $q['posts_per_page']);
-		}
-
 		// Check post status to determine if post should be displayed.
 		if ( !empty($this->posts) && ($this->is_single || $this->is_page) ) {
 			$status = get_post_status($this->posts[0]);
@@ -2754,6 +2769,18 @@
 		return $this->posts;
 	}
 
+	function set_found_posts( $q, $limits ) {
+		global $wpdb;
+
+		if ( $q['no_found_rows'] || empty( $limits ) )
+			return;
+
+		$found_posts_query = apply_filters_ref_array( 'found_posts_query', array( 'SELECT FOUND_ROWS()', $this ) );
+		$this->found_posts = $wpdb->get_var( $found_posts_query );
+		$this->found_posts = apply_filters_ref_array( 'found_posts', array( $this->found_posts, $this ) );
+		$this->max_num_pages = ceil( $this->found_posts / $q['posts_per_page'] );
+	}
+
 	/**
 	 * Set up the next post and iterate current post index.
 	 *
Index: wp-includes/formatting.php
===================================================================
--- wp-includes/formatting.php	(revision 19788)
+++ wp-includes/formatting.php	(working copy)
@@ -3019,4 +3019,4 @@
 	$urls_to_ping = array_map( 'esc_url_raw', $urls_to_ping );
 	$urls_to_ping = implode( "\n", $urls_to_ping );
 	return apply_filters( 'sanitize_trackback_urls', $urls_to_ping, $to_ping );
-}
+}
\ No newline at end of file
Index: wp-includes/pluggable.php
===================================================================
--- wp-includes/pluggable.php	(revision 19788)
+++ wp-includes/pluggable.php	(working copy)
@@ -139,13 +139,7 @@
 function cache_users( $user_ids ) {
 	global $wpdb;
 
-	$clean = array();
-	foreach ( $user_ids as $id ) {
-		$id = (int) $id;
-		if ( !wp_cache_get( $id, 'users' ) ) {
-			$clean[] = $id;
-		}
-	}
+	$clean = _get_non_cached_ids( $user_ids, 'users' );
 
 	if ( empty( $clean ) )
 		return;
