Commit 07f77bb2 authored by unknown's avatar unknown

WL#2985 "Partition pruning": addition2: perform partition pruning for

single-table UPDATE/DELETE.


mysql-test/r/partition_pruning.result:
  WL#2985 "Partition pruning": addition2: perform partition pruning for UPDATE/DELETE:
  testcases added
mysql-test/t/partition_pruning.test:
  WL#2985 "Partition pruning": addition2: perform partition pruning for UPDATE/DELETE:
  testcases added
sql/sql_delete.cc:
  WL#2985 "Partition pruning": addition2: perform partition pruning for UPDATE/DELETE:
  Added partition pruning call in mysql_delete()
sql/sql_update.cc:
  WL#2985 "Partition pruning": addition2: perform partition pruning for UPDATE/DELETE:
  Added partition pruning call in mysql_update()
parent 06d50ec9
...@@ -304,3 +304,42 @@ id select_type table partitions type possible_keys key key_len ref rows Extra ...@@ -304,3 +304,42 @@ id select_type table partitions type possible_keys key key_len ref rows Extra
explain partitions select * from t1 where b > 1 and b < 3 and (a =1 or a =2); explain partitions select * from t1 where b > 1 and b < 3 and (a =1 or a =2);
id select_type table partitions type possible_keys key key_len ref rows Extra id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p1_sp2,p2_sp2 ALL NULL NULL NULL NULL 3 Using where 1 SIMPLE t1 p1_sp2,p2_sp2 ALL NULL NULL NULL NULL 3 Using where
drop table t1;
create table t1 (a int) partition by list(a) (
partition p0 values in (1,2),
partition p1 values in (3,4)
);
insert into t1 values (1),(1),(2),(2),(3),(4),(3),(4);
flush status;
update t1 set a=100 where a=5;
show status like 'Handler_read_rnd_next';
Variable_name Value
Handler_read_rnd_next 0
flush status;
update t1 set a=100 where a+1=5+1;
show status like 'Handler_read_rnd_next';
Variable_name Value
Handler_read_rnd_next 10
flush status;
delete from t1 where a=5;
show status like 'Handler_read_rnd_next';
Variable_name Value
Handler_read_rnd_next 0
flush status;
delete from t1 where a+1=5+1;
show status like 'Handler_read_rnd_next';
Variable_name Value
Handler_read_rnd_next 10
create table t2 like t1;
insert into t2 select * from t2;
flush status;
update t1,t2 set t1.a=1000, t2.a=1000 where t1.a=5 and t2.a=5;
show status like 'Handler_read_rnd_next';
Variable_name Value
Handler_read_rnd_next 3
flush status;
delete t1,t2 from t1, t2 where t1.a=5 and t2.a=5;
show status like 'Handler_read_rnd_next';
Variable_name Value
Handler_read_rnd_next 3
drop table t1,t2;
...@@ -269,6 +269,52 @@ insert into t1 values (1,1),(2,2),(3,3); ...@@ -269,6 +269,52 @@ insert into t1 values (1,1),(2,2),(3,3);
explain partitions select * from t1 where b > 1 and b < 3; explain partitions select * from t1 where b > 1 and b < 3;
explain partitions select * from t1 where b > 1 and b < 3 and (a =1 or a =2); explain partitions select * from t1 where b > 1 and b < 3 and (a =1 or a =2);
drop table t1;
# Test partition pruning for single-table UPDATE/DELETE.
# TODO: Currently we test only "all partitions pruned away" case. Add more
# tests when the patch that makes use of partition pruning results at
# execution phase is pushed.
create table t1 (a int) partition by list(a) (
partition p0 values in (1,2),
partition p1 values in (3,4)
);
insert into t1 values (1),(1),(2),(2),(3),(4),(3),(4);
# This won't do any table access
flush status;
update t1 set a=100 where a=5;
show status like 'Handler_read_rnd_next';
# ... as compared to this, which will scan both partitions
flush status;
update t1 set a=100 where a+1=5+1;
show status like 'Handler_read_rnd_next';
# Same as above for DELETE:
flush status;
delete from t1 where a=5;
show status like 'Handler_read_rnd_next';
flush status;
delete from t1 where a+1=5+1;
show status like 'Handler_read_rnd_next';
# Same as above multi-table UPDATE/DELETE
create table t2 like t1;
insert into t2 select * from t2;
flush status;
update t1,t2 set t1.a=1000, t2.a=1000 where t1.a=5 and t2.a=5;
show status like 'Handler_read_rnd_next';
# ^ This shows 3 accesses, these are caused by const table reads.
# They should vanish when partition pruning results are used.
flush status;
delete t1,t2 from t1, t2 where t1.a=5 and t2.a=5;
show status like 'Handler_read_rnd_next';
drop table t1,t2;
# No tests for NULLs in RANGE(monotonic_expr()) - they depend on BUG#15447 # No tests for NULLs in RANGE(monotonic_expr()) - they depend on BUG#15447
# being fixed. # being fixed.
...@@ -100,6 +100,21 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ...@@ -100,6 +100,21 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
/* Handler didn't support fast delete; Delete rows one by one */ /* Handler didn't support fast delete; Delete rows one by one */
} }
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (prune_partitions(thd, table, conds))
{
free_underlaid_joins(thd, select_lex);
thd->row_count_func= 0;
send_ok(thd); // No matching records
DBUG_RETURN(0);
}
/*
Update the table->records number (note: we probably could remove the
previous file->info() call)
*/
table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
#endif
table->used_keys.clear_all(); table->used_keys.clear_all();
table->quick_keys.clear_all(); // Can't use 'only index' table->quick_keys.clear_all(); // Can't use 'only index'
select=make_select(table, 0, 0, conds, 0, &error); select=make_select(table, 0, 0, conds, 0, &error);
...@@ -111,13 +126,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ...@@ -111,13 +126,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
free_underlaid_joins(thd, select_lex); free_underlaid_joins(thd, select_lex);
thd->row_count_func= 0; thd->row_count_func= 0;
send_ok(thd,0L); send_ok(thd,0L);
/* /*
We don't need to call reset_auto_increment in this case, because We don't need to call reset_auto_increment in this case, because
mysql_truncate always gives a NULL conds argument, hence we never mysql_truncate always gives a NULL conds argument, hence we never
get here. get here.
*/ */
DBUG_RETURN(0); // Nothing to delete DBUG_RETURN(0); // Nothing to delete
} }
......
...@@ -244,6 +244,21 @@ int mysql_update(THD *thd, ...@@ -244,6 +244,21 @@ int mysql_update(THD *thd,
} }
// Don't count on usage of 'only index' when calculating which key to use // Don't count on usage of 'only index' when calculating which key to use
table->used_keys.clear_all(); table->used_keys.clear_all();
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (prune_partitions(thd, table, conds))
{
free_underlaid_joins(thd, select_lex);
send_ok(thd); // No matching records
DBUG_RETURN(0);
}
/*
Update the table->records number (note: we probably could remove the
previous file->info() call)
*/
table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
#endif
select= make_select(table, 0, 0, conds, 0, &error); select= make_select(table, 0, 0, conds, 0, &error);
if (error || !limit || if (error || !limit ||
(select && select->check_quick(thd, safe_update, limit))) (select && select->check_quick(thd, safe_update, limit)))
......
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