Loading mysql-test/r/partition_pruning.result +39 −0 Original line number Diff line number Diff line Loading @@ -510,3 +510,42 @@ show status like 'Handler_read_next'; Variable_name Value Handler_read_next 0 drop table t1, t2; 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; mysql-test/t/partition_pruning.test +46 −0 Original line number Diff line number Diff line Loading @@ -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 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; # WL# 2986 DROP TABLE IF EXISTS `t1`; Loading sql/sql_delete.cc +15 −2 Original line number Diff line number Diff line Loading @@ -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 */ } #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->quick_keys.clear_all(); // Can't use 'only index' select=make_select(table, 0, 0, conds, 0, &error); Loading @@ -111,13 +126,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, free_underlaid_joins(thd, select_lex); thd->row_count_func= 0; send_ok(thd,0L); /* We don't need to call reset_auto_increment in this case, because mysql_truncate always gives a NULL conds argument, hence we never get here. */ DBUG_RETURN(0); // Nothing to delete } Loading sql/sql_update.cc +15 −0 Original line number Diff line number Diff line Loading @@ -244,6 +244,21 @@ int mysql_update(THD *thd, } // Don't count on usage of 'only index' when calculating which key to use 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); if (error || !limit || (select && select->check_quick(thd, safe_update, limit))) Loading Loading
mysql-test/r/partition_pruning.result +39 −0 Original line number Diff line number Diff line Loading @@ -510,3 +510,42 @@ show status like 'Handler_read_next'; Variable_name Value Handler_read_next 0 drop table t1, t2; 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;
mysql-test/t/partition_pruning.test +46 −0 Original line number Diff line number Diff line Loading @@ -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 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; # WL# 2986 DROP TABLE IF EXISTS `t1`; Loading
sql/sql_delete.cc +15 −2 Original line number Diff line number Diff line Loading @@ -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 */ } #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->quick_keys.clear_all(); // Can't use 'only index' select=make_select(table, 0, 0, conds, 0, &error); Loading @@ -111,13 +126,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, free_underlaid_joins(thd, select_lex); thd->row_count_func= 0; send_ok(thd,0L); /* We don't need to call reset_auto_increment in this case, because mysql_truncate always gives a NULL conds argument, hence we never get here. */ DBUG_RETURN(0); // Nothing to delete } Loading
sql/sql_update.cc +15 −0 Original line number Diff line number Diff line Loading @@ -244,6 +244,21 @@ int mysql_update(THD *thd, } // Don't count on usage of 'only index' when calculating which key to use 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); if (error || !limit || (select && select->check_quick(thd, safe_update, limit))) Loading