Index: wp-includes/post.php
===================================================================
--- wp-includes/post.php	(revision 4417)
+++ wp-includes/post.php	(working copy)
@@ -274,34 +274,13 @@
 
 	$post_id = (int) $post_id;
 
-	if ( isset($post_meta_cache[$post_id][$key]) ) {
-		if ( $single ) {
-			return maybe_unserialize( $post_meta_cache[$post_id][$key][0] );
-		} else {
-			return maybe_unserialize( $post_meta_cache[$post_id][$key] );
-		}
-	}
+	if ( !isset($post_meta_cache[$post_id]) )
+		update_postmeta_cache($post_id);
 
-	$metalist = $wpdb->get_results("SELECT meta_value FROM $wpdb->postmeta WHERE post_id = '$post_id' AND meta_key = '$key'", ARRAY_N);
-
-	$values = array();
-	if ( $metalist ) {
-		foreach ($metalist as $metarow) {
-			$values[] = $metarow[0];
-		}
-	}
-
-	if ( $single ) {
-		if ( count($values) ) {
-			$return = maybe_unserialize( $values[0] );
-		} else {
-			return '';
-		}
-	} else {
-		$return = $values;
-	}
-
-	return maybe_unserialize($return);
+	if ( $single )
+		return maybe_unserialize($post_meta_cache[$post_id][$key][0]);
+	else
+		return maybe_unserialize($post_meta_cache[$post_id][$key]);
 }
 
 function update_post_meta($post_id, $key, $value, $prev_value = '') {
@@ -340,43 +319,24 @@
 }
 
 
-function get_post_custom( $post_id = 0 ) {
+function get_post_custom($post_id = 0) {
 	global $id, $post_meta_cache, $wpdb;
 
-	if ( ! $post_id )
+	if ( !$post_id )
 		$post_id = $id;
 
 	$post_id = (int) $post_id;
 
-	if ( isset($post_meta_cache[$post_id]) )
-		return $post_meta_cache[$post_id];
+	if ( !isset($post_meta_cache[$post_id]) )
+		update_postmeta_cache($post_id);
 
-	if ( $meta_list = $wpdb->get_results("SELECT post_id, meta_key, meta_value FROM $wpdb->postmeta	WHERE post_id = '$post_id' ORDER BY post_id, meta_key", ARRAY_A) ) {
-		// Change from flat structure to hierarchical:
-		$post_meta_cache = array();
-		foreach ( $meta_list as $metarow ) {
-			$mpid = (int) $metarow['post_id'];
-			$mkey = $metarow['meta_key'];
-			$mval = $metarow['meta_value'];
-
-			// Force subkeys to be array type:
-			if ( !isset($post_meta_cache[$mpid]) || !is_array($post_meta_cache[$mpid]) )
-				$post_meta_cache[$mpid] = array();
-
-			if ( !isset($post_meta_cache[$mpid]["$mkey"]) || !is_array($post_meta_cache[$mpid]["$mkey"]) )
-				$post_meta_cache[$mpid]["$mkey"] = array();
-
-			// Add a value to the current pid/key:
-			$post_meta_cache[$mpid][$mkey][] = $mval;
-		}
-		return $post_meta_cache[$mpid];
-	}
+	return $post_meta_cache[$post_id];
 }
 
 function get_post_custom_keys( $post_id = 0 ) {
 	$custom = get_post_custom( $post_id );
 
-	if ( ! is_array($custom) )
+	if ( !is_array($custom) )
 		return;
 
 	if ( $keys = array_keys($custom) )
Index: wp-includes/functions.php
===================================================================
--- wp-includes/functions.php	(revision 4417)
+++ wp-includes/functions.php	(working copy)
@@ -563,10 +563,27 @@
 
 	update_post_category_cache($post_id_list);
 
+	update_postmeta_cache($post_id_list);
+}
+
+function update_postmeta_cache($post_id_list = '') {
+	global $wpdb, $post_meta_cache;
+
+	// We should validate this comma-separated list for the upcoming SQL query
+	$post_id_list = preg_replace('|[^0-9,]|', '', $post_id_list);
+
+	// we're marking each post as having its meta cached (with no keys -- FALSE), to prevent posts with no meta keys from being queried again
+	// any posts that DO have keys will have this FALSE overwritten with a proper array, down below
+	$post_id_array = explode(',', $post_id_list);
+	foreach ( (array) $post_id_array as $pid )
+		$post_meta_cache[$pid] = false;
+
 	// Get post-meta info
 	if ( $meta_list = $wpdb->get_results("SELECT post_id, meta_key, meta_value FROM $wpdb->postmeta WHERE post_id IN($post_id_list) ORDER BY post_id, meta_key", ARRAY_A) ) {
 		// Change from flat structure to hierarchical:
-		$post_meta_cache = array();
+		if ( !isset($post_meta_cache) )
+			$post_meta_cache = array();
+
 		foreach ($meta_list as $metarow) {
 			$mpid = (int) $metarow['post_id'];
 			$mkey = $metarow['meta_key'];
