diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 41620bb6e7f..0b415587f47 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -1134,3 +1134,15 @@ id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	ref	salary	salary	5	const	1	Using where
 2	SUBQUERY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Select tables optimized away
 drop table t1;
+create table t1 (a int, b int);
+create table t2 (a int, b int);
+create table t3 (a int, b int);
+insert into t1 values (0,100),(1,2), (1,3), (2,2), (2,7), (2,-1), (3,10);
+insert into t2 values (0,0), (1,1), (2,1), (3,1), (4,1);
+insert into t3 values (3,3), (2,2), (1,1);
+select a,(select count(distinct t1.b) as sum from t1,t2 where t1.a=t2.a and t2.b > 0 and t1.a <= t3.b group by t1.a order by sum limit 1) from t3;
+a	(select count(distinct t1.b) as sum from t1,t2 where t1.a=t2.a and t2.b > 0 and t1.a <= t3.b group by t1.a order by sum limit 1)
+3	1
+2	2
+1	2
+drop table t1,t2,t3;
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 8377a756c5b..b8e820a7f68 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -716,3 +716,15 @@ create table t1 (id int not null auto_increment primary key, salary int, key(sal
 insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000);
 explain SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1);
 drop table t1;
+
+#
+# alloc_group_fields() working
+#
+create table t1 (a int, b int);
+create table t2 (a int, b int);
+create table t3 (a int, b int);
+insert into t1 values (0,100),(1,2), (1,3), (2,2), (2,7), (2,-1), (3,10);
+insert into t2 values (0,0), (1,1), (2,1), (3,1), (4,1);
+insert into t3 values (3,3), (2,2), (1,1); 
+select a,(select count(distinct t1.b) as sum from t1,t2 where t1.a=t2.a and t2.b > 0 and t1.a <= t3.b group by t1.a order by sum limit 1) from t3;
+drop table t1,t2,t3;
\ No newline at end of file
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 4167da5802a..6f692b3bfe7 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -137,6 +137,7 @@ static ORDER *create_distinct_group(THD *thd, ORDER *order,
 static bool test_if_subpart(ORDER *a,ORDER *b);
 static TABLE *get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables);
 static void calc_group_buffer(JOIN *join,ORDER *group);
+static bool make_group_fields(JOIN *main_join, JOIN *curr_join);
 static bool alloc_group_fields(JOIN *join,ORDER *group);
 static bool make_sum_func_list(JOIN *join,List<Item> &fields);
 // Create list for using with tempory table
@@ -1103,12 +1104,12 @@ JOIN::exec()
 	  DBUG_VOID_RETURN;
 	curr_join->exec_tmp_table2= exec_tmp_table2;
       }
-      if (group_list)
+      if (curr_join->group_list)
       {
 	thd->proc_info= "Creating sort index";
 	if (create_sort_index(thd, curr_join->join_tab, curr_join->group_list,
 			      HA_POS_ERROR, HA_POS_ERROR) ||
-	    alloc_group_fields(curr_join, curr_join->group_list))
+	    make_group_fields(this, curr_join))
 	{
 	  DBUG_VOID_RETURN;
 	}
@@ -1176,7 +1177,10 @@ JOIN::exec()
   if (curr_join->group || curr_join->tmp_table_param.sum_func_count ||
       (procedure && (procedure->flags & PROC_GROUP)))
   {
-    alloc_group_fields(curr_join, curr_join->group_list);
+    if (make_group_fields(this, curr_join))
+    {
+      DBUG_VOID_RETURN;
+    }
     if (!items3)
     {
       if (!items0)
@@ -7525,6 +7529,37 @@ calc_group_buffer(JOIN *join,ORDER *group)
   join->tmp_table_param.group_null_parts=null_parts;
 }
 
+/*
+  alloc group fields or take prepared (chached)
+
+  SYNOPSYS
+    make_group_fields()
+    main_join - join of current select
+    curr_join - current join (join of current select or temporary copy of it)
+
+  RETURN
+    0 - ok
+    1 - failed
+*/
+
+static bool
+make_group_fields(JOIN *main_join, JOIN *curr_join)
+{
+    if (main_join->group_fields_cache.elements)
+    {
+      curr_join->group_fields= main_join->group_fields_cache;
+      curr_join->sort_and_group= 1;
+    }
+    else
+    {
+      if (alloc_group_fields(curr_join, curr_join->group_list))
+      {
+	return (1);
+      }
+      main_join->group_fields_cache= curr_join->group_fields;
+    }
+    return (0);
+}
 
 /*
   Get a list of buffers for saveing last group
@@ -7551,6 +7586,7 @@ alloc_group_fields(JOIN *join,ORDER *group)
 static int
 test_if_group_changed(List<Item_buff> &list)
 {
+  DBUG_ENTER("test_if_group_changed");
   List_iterator<Item_buff> li(list);
   int idx= -1,i;
   Item_buff *buff;
@@ -7560,7 +7596,8 @@ test_if_group_changed(List<Item_buff> &list)
     if (buff->cmp())
       idx=i;
   }
-  return idx;
+  DBUG_PRINT("info", ("idx: %d", idx));
+  DBUG_RETURN(idx);
 }
 
 
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 7f3669f7478..1e0f7314e7c 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -127,7 +127,7 @@ class JOIN :public Sql_alloc
   POSITION positions[MAX_TABLES+1],best_positions[MAX_TABLES+1];
   double   best_read;
   List<Item> *fields;
-  List<Item_buff> group_fields;
+  List<Item_buff> group_fields, group_fields_cache;
   TABLE    *tmp_table;
   // used to store 2 possible tmp table of SELECT
   TABLE    *exec_tmp_table1, *exec_tmp_table2;