Index: wp-includes/category.php
===================================================================
--- wp-includes/category.php	(revision 5175)
+++ wp-includes/category.php	(working copy)
@@ -109,8 +109,11 @@
 		unset($cat_stamps);
 	}
 
-	if ( $child_of || $hierarchical )
-		$categories = & _get_cat_children($child_of, $categories);
+	if ( $child_of || $hierarchical ) {
+		$children = _get_category_hierarchy();
+		if ( ! empty($children) )
+			$categories = & _get_cat_children($child_of, $categories);
+	}
 
 	// Update category counts to include children.
 	if ( $pad_counts )
@@ -260,12 +263,16 @@
 		return array();
 
 	$category_list = array();
+	$children = _get_category_hierarchy();
 	foreach ( $categories as $category ) {
 		if ( $category->cat_ID == $category_id )
 			continue;
 
 		if ( $category->category_parent == $category_id ) {
 			$category_list[] = $category;
+			if ( !isset($children[$category->cat_ID]) )
+				continue;
+			
 			if ( $children = _get_cat_children($category->cat_ID, $categories) )
 				$category_list = array_merge($category_list, $children);
 		}
@@ -313,4 +320,19 @@
 			$cats[$id]->{'link' == $type ? 'link_count' : 'category_count'} = count($items);
 }
 
+function _get_category_hierarchy() {
+	$children = get_option('category_children');
+	if ( is_array($children) )
+		return $children;
+
+	$children = array();
+	$categories = get_categories('hide_empty=0&hierarchical=0');
+	foreach ( $categories as $cat ) {
+		if ( $cat->category_parent > 0 )
+			$children[$cat->category_parent][] = $cat->ID;
+	}
+	update_option('category_children', $children);
+
+	return $children;
+}
 ?>
Index: wp-includes/functions.php
===================================================================
--- wp-includes/functions.php	(revision 5175)
+++ wp-includes/functions.php	(working copy)
@@ -749,6 +749,7 @@
 	wp_cache_delete($id, 'category');
 	wp_cache_delete('all_category_ids', 'category');
 	wp_cache_delete('get_categories', 'category');
+	delete_option('category_children');
 }
 
 /*
