From 07a52afd008b0822b38044d047f8c306880412b0 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Sun, 16 Mar 2014 14:33:37 +0100 Subject: [PATCH] MDEV-4410: update does not want to use a covering index, but select uses it - If an UPDATE 1) modifies the key it is using, and 2) has ORDER BY ... LIMIT which matches the key it is using, Then we should use "Using buffer", not "Using filesort". --- mysql-test/r/update.result | 27 +++++++++++++++++++++++++++ mysql-test/t/update.test | 22 ++++++++++++++++++++++ sql/sql_update.cc | 2 +- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result index 3f3a3ac07df..bc0f9411d15 100644 --- a/mysql-test/r/update.result +++ b/mysql-test/r/update.result @@ -603,3 +603,30 @@ Variable_name Value Handler_update 5 ROLLBACK; DROP TABLE t1, t2; +# +# MDEV-4410: update does not want to use a covering index, but select uses it. +# +create table t2(a int); +insert into t2 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 (key1 int, col1 int, key(key1)); +insert into t1 +select A.a + 10 * B.a + 100 * C.a, 1234 from t2 A, t2 B, t2 C; +# This must not have "Using filesort": +explain +update t1 set key1=key1+1 where key1 between 10 and 110 order by key1 limit 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range key1 key1 5 NULL 100 Using where; Using buffer +flush status; +update t1 set key1=key1+1 where key1 between 10 and 110 order by key1 limit 2; +show status like 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 1 +Handler_read_last 0 +Handler_read_next 1 +Handler_read_prev 0 +Handler_read_rnd 2 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 0 +drop table t1, t2; +# End of MariaDB 10.0 tests diff --git a/mysql-test/t/update.test b/mysql-test/t/update.test index daa20509ab6..09d32966c50 100644 --- a/mysql-test/t/update.test +++ b/mysql-test/t/update.test @@ -544,3 +544,25 @@ SHOW STATUS LIKE 'HANDLER_UPDATE'; ROLLBACK; DROP TABLE t1, t2; +--echo # +--echo # MDEV-4410: update does not want to use a covering index, but select uses it. +--echo # +create table t2(a int); +insert into t2 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); + +create table t1 (key1 int, col1 int, key(key1)); +insert into t1 +select A.a + 10 * B.a + 100 * C.a, 1234 from t2 A, t2 B, t2 C; + +--echo # This must not have "Using filesort": +explain +update t1 set key1=key1+1 where key1 between 10 and 110 order by key1 limit 2; + +flush status; +update t1 set key1=key1+1 where key1 between 10 and 110 order by key1 limit 2; +# Handler_read_next should be 1 (due to LIMIT), not 100: +show status like 'Handler_read%'; + +drop table t1, t2; + +--echo # End of MariaDB 10.0 tests diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 32190a3a8d4..290f6c6329c 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -502,7 +502,7 @@ int mysql_update(THD *thd, if (used_key_is_modified || order || partition_key_modified(table, table->write_set)) { - if (order && (need_sort || used_key_is_modified)) + if (order && need_sort) query_plan.using_filesort= true; else query_plan.using_io_buffer= true;