Index: wp-includes/query.php
===================================================================
--- wp-includes/query.php	(revision 31418)
+++ wp-includes/query.php	(working copy)
@@ -3278,6 +3278,37 @@
 		}
 
 		/**
+		 * Explicitly add sticky posts to the query
+		 */
+		$sticky_posts = get_option('sticky_posts');
+		if ( $this->is_home && !$q['ignore_sticky_posts'] && !empty( $sticky_posts ) ) {
+			// Grab only published sticky posts of our desired post type(s)
+			$stickies_query = new WP_Query( array(
+				'post__in' => $sticky_posts,
+				'post_type' => $post_type,
+				'post_status' => 'publish',
+				'fields' => 'ids',
+				'ignore_sticky_posts' => true,
+				'posts_per_page' => count( $sticky_posts )
+			) );
+
+			$queried_stickies = $stickies_query->posts;
+
+			if( !empty( $queried_stickies ) ) {
+				$post__in_sticky = implode(',', array_map( 'absint', $queried_stickies ) );
+				$where = "AND ((1=1 " . $where . ") OR {$wpdb->posts}.ID IN ($post__in_sticky))";
+				$sticky_orderby = "FIELD( {$wpdb->posts}.ID, $post__in_sticky ) DESC";
+
+				if($orderby) {
+					$orderby = $sticky_orderby . ', ' . $orderby;
+				}
+				else {
+					$orderby = $sticky_orderby;
+				}
+			}
+		}
+
+		/**
 		 * Fires to announce the query's current selection parameters.
 		 *
 		 * For use by caching plugins.
@@ -3577,47 +3608,7 @@
 			}
 		}
 
-		// Put sticky posts at the top of the posts array
-		$sticky_posts = get_option('sticky_posts');
-		if ( $this->is_home && $page <= 1 && is_array($sticky_posts) && !empty($sticky_posts) && !$q['ignore_sticky_posts'] ) {
-			$num_posts = count($this->posts);
-			$sticky_offset = 0;
-			// Loop over posts and relocate stickies to the front.
-			for ( $i = 0; $i < $num_posts; $i++ ) {
-				if ( in_array($this->posts[$i]->ID, $sticky_posts) ) {
-					$sticky_post = $this->posts[$i];
-					// Remove sticky from current position
-					array_splice($this->posts, $i, 1);
-					// Move to front, after other stickies
-					array_splice($this->posts, $sticky_offset, 0, array($sticky_post));
-					// Increment the sticky offset. The next sticky will be placed at this offset.
-					$sticky_offset++;
-					// Remove post from sticky posts array
-					$offset = array_search($sticky_post->ID, $sticky_posts);
-					unset( $sticky_posts[$offset] );
-				}
-			}
 
-			// If any posts have been excluded specifically, Ignore those that are sticky.
-			if ( !empty($sticky_posts) && !empty($q['post__not_in']) )
-				$sticky_posts = array_diff($sticky_posts, $q['post__not_in']);
-
-			// Fetch sticky posts that weren't in the query results
-			if ( !empty($sticky_posts) ) {
-				$stickies = get_posts( array(
-					'post__in' => $sticky_posts,
-					'post_type' => $post_type,
-					'post_status' => 'publish',
-					'nopaging' => true
-				) );
-
-				foreach ( $stickies as $sticky_post ) {
-					array_splice( $this->posts, $sticky_offset, 0, array( $sticky_post ) );
-					$sticky_offset++;
-				}
-			}
-		}
-
 		if ( ! $q['suppress_filters'] ) {
 			/**
 			 * Filter the array of retrieved posts after they've been fetched and
