diff --git a/mysql-test/r/explain_non_select.result b/mysql-test/r/explain_non_select.result
index d118cd7b4e70dff2f22b0859521a8c30ce7e2aeb..7d5228de0ee322baebf9ac26955f411683ef0b12 100644
--- a/mysql-test/r/explain_non_select.result
+++ b/mysql-test/r/explain_non_select.result
@@ -21,7 +21,7 @@ from t0 A, t0 B, t0 C;
 # This should use an index,  possible_keys=NULL because there is no WHERE
 explain delete from t1 order by a limit 2;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t1	index	NULL	a	NULL	NULL	512	
+1	SIMPLE	t1	index	NULL	a	NULL	NULL	2	
 # This should use range, possible_keys={a,b}
 explain delete from t1 where a<20 and b < 10;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
@@ -72,7 +72,7 @@ id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 # This should use an index,  possible_keys=NULL because there is no WHERE
 explain update t1 set a=a+1 order by a limit 2;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	512	
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	512	Using filesort
 # This should use range, possible_keys={a,b}
 explain update t1 set filler='fooo' where a<20 and b < 10;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
@@ -80,11 +80,11 @@ id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 # This should use ALL + filesort
 explain update t1 set filler='fooo' order by a+1 limit 2;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	512	
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	512	Using filesort
 # This should use range + using filesort
 explain update t1 set filler='fooo' where a<20 order by b limit 2;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t1	range	a	a	5	NULL	1	Using where
+1	SIMPLE	t1	range	a	a	5	NULL	1	Using where; Using filesort
 # Try some subqueries:
 explain update t1 set filler='fooo' where a < (select max(a) from t0);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 15dfe3e6c7c58c5f215de4c6ef7238946557c258..00193800b93db2ff68ca450d4c08552d1ae608bf 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -59,7 +59,7 @@ void Delete_plan::save_explain_data(Explain_query *query)
   {
     explain->deleting_all_rows= true;
     explain->select_type= "SIMPLE";
-    explain->rows= table_rows;
+    explain->rows= scanned_rows;
   }
   else
   {
@@ -161,7 +161,7 @@ void Update_plan::save_explain_data_intern(Explain_query *query,
     }
     // key_len stays NULL
   }
-  explain->rows= select ? select->records : table_rows;
+  explain->rows= scanned_rows;
 
   if (select && select->quick && 
       select->quick->get_type() == QUICK_SELECT_I::QS_TYPE_RANGE)
@@ -421,6 +421,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
   if (options & OPTION_QUICK)
     (void) table->file->extra(HA_EXTRA_QUICK);
 
+  query_plan.scanned_rows= select? select->records: table->file->stats.records;
   if (order)
   {
     table->update_const_key_parts(conds);
@@ -432,14 +433,19 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
       query_plan.index= MAX_KEY;
     }
     else
+    {
+      ha_rows scanned_limit= query_plan.scanned_rows;
       query_plan.index= get_index_for_order(order, table, select, limit,
+                                            &scanned_limit,
                                             &query_plan.using_filesort, 
                                             &reverse);
+      if (!query_plan.using_filesort)
+        query_plan.scanned_rows= scanned_limit;
+    }
   }
 
   query_plan.select= select;
   query_plan.possible_keys= select? select->possible_keys: key_map(0);
-  query_plan.table_rows= table->file->stats.records;
   
   /*
     Ok, we have generated a query plan for the DELETE.
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 9515079e75fa08a3c425a105ad70152a0acb6827..c5b9c1eada20a4c9eb526c92b8a4035b738ca041 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -2397,7 +2397,7 @@ public:
   TABLE *table;
   SQL_SELECT *select;
   uint index;
-  ha_rows table_rows; /* Use if select==NULL */
+  ha_rows scanned_rows;
   /*
     Top-level select_lex. Most of its fields are not used, we need it only to
     get to the subqueries.
@@ -2440,7 +2440,7 @@ public:
   void set_delete_all_rows(ha_rows rows_arg) 
   { 
     deleting_all_rows= true;
-    table_rows= rows_arg;
+    scanned_rows= rows_arg;
   }
 
   void save_explain_data(Explain_query *query);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index b99b41915f6421e6b2506cdc5036e540cb5a00a5..a51fcd07b58b61cf0833716f712763a5e1f75ed4 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -24126,6 +24126,8 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table,
   @param       table           Table to find a key
   @param       select          Pointer to access/update select->quick (if any)
   @param       limit           LIMIT clause parameter 
+  @param [out] scanned_limit   How many records we expect to scan
+                               Valid if *need_sort=FALSE.
   @param [out] need_sort       TRUE if filesort needed
   @param [out] reverse
     TRUE if the key is reversed again given ORDER (undefined if key == MAX_KEY)
@@ -24143,7 +24145,8 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table,
 */
 
 uint get_index_for_order(ORDER *order, TABLE *table, SQL_SELECT *select,
-                         ha_rows limit, bool *need_sort, bool *reverse)
+                         ha_rows limit, ha_rows *scanned_limit,
+                         bool *need_sort, bool *reverse)
 {
   if (!order)
   {
@@ -24185,6 +24188,7 @@ uint get_index_for_order(ORDER *order, TABLE *table, SQL_SELECT *select,
         {
           select->set_quick(reverse_quick);
           *need_sort= FALSE;
+          *scanned_limit= select->quick->records;
           return select->quick->index;
         }
         else
@@ -24213,6 +24217,7 @@ uint get_index_for_order(ORDER *order, TABLE *table, SQL_SELECT *select,
         !is_key_used(table, key, table->write_set))
     {
       *need_sort= FALSE;
+      *scanned_limit= limit;
       *reverse= (direction < 0);
       return key;
     }
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 71760ea76f5992718f5299460b3fb1cfb7cc2f74..48515042a02c888d30e4a9b95324a2307f6bfbab 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -1833,7 +1833,8 @@ int print_fake_select_lex_join(select_result_sink *result, bool on_the_fly,
                                SELECT_LEX *select_lex, uint8 select_options);
 
 uint get_index_for_order(ORDER *order, TABLE *table, SQL_SELECT *select,
-                         ha_rows limit, bool *need_sort, bool *reverse);
+                         ha_rows limit, ha_rows *scanned_limit, 
+                         bool *need_sort, bool *reverse);
 ORDER *simple_remove_const(ORDER *order, COND *where);
 bool const_expression_in_where(COND *cond, Item *comp_item,
                                Field *comp_field= NULL,
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 5b2333657e1a137d642868a82c7d720508afb500..a5f81a9e89ec1f15a45db9871c9883ee08593320 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -456,6 +456,7 @@ int mysql_update(THD *thd,
 
   table->update_const_key_parts(conds);
   order= simple_remove_const(order, conds);
+  query_plan.scanned_rows= select? select->records: table->file->stats.records;
         
   if (select && select->quick && select->quick->unique_key_range())
   { // Single row select (always "ordered"): Ok to use with key field UPDATE
@@ -465,8 +466,12 @@ int mysql_update(THD *thd,
   }
   else
   {
+    ha_rows scanned_limit= query_plan.scanned_rows;
     query_plan.index= get_index_for_order(order, table, select, limit,
-                                          &need_sort, &reverse);
+                                          &scanned_limit, &need_sort, &reverse);
+    if (!need_sort)
+      query_plan.scanned_rows= scanned_limit;
+
     if (select && select->quick)
     {
       DBUG_ASSERT(need_sort || query_plan.index == select->quick->index);
@@ -492,7 +497,6 @@ int mysql_update(THD *thd,
      - if we're running EXPLAIN UPDATE, get out
   */
   query_plan.select= select;
-  query_plan.table_rows= table->file->stats.records;
   query_plan.possible_keys= select? select->possible_keys: key_map(0);
   
   if (used_key_is_modified || order ||
@@ -504,7 +508,6 @@ int mysql_update(THD *thd,
       query_plan.using_io_buffer= true;
   }
 
-  query_plan.save_explain_data(thd->lex->explain);
 
   /*
     Ok, we have generated a query plan for the UPDATE.
@@ -513,6 +516,8 @@ int mysql_update(THD *thd,
   */
   if (thd->lex->describe)
     goto exit_without_my_ok;
+  query_plan.save_explain_data(thd->lex->explain);
+
   thd->apc_target.enable();
   apc_target_enabled= true;
   DBUG_EXECUTE_IF("show_explain_probe_update_exec_start", 
@@ -1041,6 +1046,7 @@ err:
 
 exit_without_my_ok:
   DBUG_ASSERT(!apc_target_enabled);
+  query_plan.save_explain_data(thd->lex->explain);
 
   int err2= thd->lex->explain->send_explain(thd);