Commit 07a52afd authored by Sergey Petrunya's avatar Sergey Petrunya

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". 
parent 365ba070
...@@ -603,3 +603,30 @@ Variable_name Value ...@@ -603,3 +603,30 @@ Variable_name Value
Handler_update 5 Handler_update 5
ROLLBACK; ROLLBACK;
DROP TABLE t1, t2; 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
...@@ -544,3 +544,25 @@ SHOW STATUS LIKE 'HANDLER_UPDATE'; ...@@ -544,3 +544,25 @@ SHOW STATUS LIKE 'HANDLER_UPDATE';
ROLLBACK; ROLLBACK;
DROP TABLE t1, t2; 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
...@@ -502,7 +502,7 @@ int mysql_update(THD *thd, ...@@ -502,7 +502,7 @@ int mysql_update(THD *thd,
if (used_key_is_modified || order || if (used_key_is_modified || order ||
partition_key_modified(table, table->write_set)) partition_key_modified(table, table->write_set))
{ {
if (order && (need_sort || used_key_is_modified)) if (order && need_sort)
query_plan.using_filesort= true; query_plan.using_filesort= true;
else else
query_plan.using_io_buffer= true; query_plan.using_io_buffer= true;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment