diff --git a/mysql-test/main/derived_split_innodb.result b/mysql-test/main/derived_split_innodb.result
index 9569b85c234..9ea3d0f1396 100644
--- a/mysql-test/main/derived_split_innodb.result
+++ b/mysql-test/main/derived_split_innodb.result
@@ -129,7 +129,7 @@ left join
 on t1.f1=t.f1;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t	const	f2	NULL	NULL	NULL	0	Impossible ON condition
-1	PRIMARY	<derived2>	const	key1	NULL	NULL	NULL	0	Impossible ON condition
+1	PRIMARY	<derived2>	const	key0,key1	NULL	NULL	NULL	0	Impossible ON condition
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	
 2	DERIVED	t2	ALL	PRIMARY	NULL	NULL	NULL	3	Using temporary; Using filesort
 set statement optimizer_switch='split_materialized=off' for explain select t.f2
@@ -139,7 +139,7 @@ left join
 on t1.f1=t.f1;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t	const	f2	NULL	NULL	NULL	0	Impossible ON condition
-1	PRIMARY	<derived3>	const	key1	NULL	NULL	NULL	0	Impossible ON condition
+1	PRIMARY	<derived3>	const	key0,key1	NULL	NULL	NULL	0	Impossible ON condition
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	3	
 3	DERIVED	t2	index	NULL	PRIMARY	4	NULL	3	
 drop view v1;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index f0bb7132353..506d4912457 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -13795,7 +13795,7 @@ bool generate_derived_keys_for_table(KEYUSE *keyuse, uint count, uint keys)
                                (uchar *) &first_keyuse,
                                FALSE))
           return TRUE;
-        table->reginfo.join_tab->keys.set_bit(table->s->keys);
+        table->reginfo.join_tab->keys.set_bit(table->s->keys - 1);
         tab= table->reginfo.join_tab;
         for (uint i=0; i < parts; i++)
           tab->key_dependent|= save_first_keyuse[i].used_tables;
@@ -13912,18 +13912,12 @@ void JOIN::drop_unused_derived_keys()
     if (!tmp_tbl->pos_in_table_list->is_materialized_derived())
       continue;
     if (tmp_tbl->max_keys > 1 && !tab->is_ref_for_hash_join())
-      tmp_tbl->use_index(tab->ref.key);
+      tmp_tbl->use_index(tab->ref.key, &tab->keys);
     if (tmp_tbl->s->keys)
     {
       if (tab->ref.key >= 0 && tab->ref.key < MAX_KEY)
         tab->ref.key= 0;
-      else
-      {
-        tmp_tbl->s->keys= 0;
-        tmp_tbl->s->uniques= 0;
-      }
     }
-    tab->keys= (key_map) (tmp_tbl->s->keys || tmp_tbl->s->uniques ? 1 : 0);
   }
 }
 
diff --git a/sql/table.cc b/sql/table.cc
index f320710fb9a..24cc95402bb 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -8458,26 +8458,57 @@ bool TABLE::add_tmp_key(uint key, uint key_parts,
   @brief
   Drop all indexes except specified one.
 
-  @param key_to_save the key to save
+  @param  key_to_save   The key to save
+  @param  map_to_update Bitmap showing some of the table's keys. Update it
+                        to show the same keys, if they are not dropped.
 
   @details
-  Drop all indexes on this table except 'key_to_save'. The saved key becomes
-  key #0. Memory occupied by key parts of dropped keys are freed.
-  If the 'key_to_save' is negative then all keys are freed.
+  Drop all indexes on this table except 'key_to_save' and unique keys.
+
+  The saved key becomes key #0. If key_to_save=-1 then only unique keys
+  remain.
 */
 
-void TABLE::use_index(int key_to_save)
+void TABLE::use_index(int key_to_save, key_map *map_to_update)
 {
-  uint i= 1;
   DBUG_ASSERT(!created && key_to_save < (int)s->keys);
-  if (key_to_save >= 0)
-    /* Save the given key. */
-    memmove(key_info, key_info + key_to_save, sizeof(KEY));
-  else
-    /* Drop all keys; */
-    i= 0;
+  uint saved_keys= 0;
+  key_map new_bitmap;
+  new_bitmap.clear_all();
+
+  /*
+    If we have key_to_save, move it to be key#0.
+  */
+  if (key_to_save != -1)
+  {
+    // try! if (map_to_update->is_set(key_to_save))
+      new_bitmap.set_bit(saved_keys);
+
+    KEY tmp_buff= key_info[saved_keys];
+    key_info[saved_keys]= key_info[key_to_save];
+    key_info[key_to_save]= tmp_buff;
+    saved_keys++;
+  }
+
+  /*
+    Now, move all unique keys to the front.
+  */
+  for (uint i= saved_keys; i < s->keys; i++)
+  {
+    if (key_info[i].flags & HA_NOSAME)
+    {
+      if (map_to_update->is_set(i))
+        new_bitmap.set_bit(saved_keys);
+
+      KEY tmp_buff= key_info[i];
+      key_info[i]= key_info[saved_keys];
+      key_info[saved_keys]= tmp_buff;
+      saved_keys++;
+    }
+  }
 
-  s->keys= i;
+  *map_to_update= new_bitmap;
+  s->keys= saved_keys;
 }
 
 /*
diff --git a/sql/table.h b/sql/table.h
index add1871e899..086f46970e9 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -1678,7 +1678,7 @@ struct TABLE
                    bool unique);
   void create_key_part_by_field(KEY_PART_INFO *key_part_info,
                                 Field *field, uint fieldnr);
-  void use_index(int key_to_save);
+  void use_index(int key_to_save, key_map *map_to_update);
   void set_table_map(table_map map_arg, uint tablenr_arg)
   {
     map= map_arg;
