1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

MDEV-16188 Introduced the notion of adjusted filter gain.

Due to inconsistent usage of different cost models to calculate
the cost of ref accesses we have to make the calculation of the
gain promising by usage a range filter more complex.
This commit is contained in:
Igor Babaev
2019-02-14 00:15:48 -08:00
parent 76c34a74a8
commit e1de23b8d5
15 changed files with 181 additions and 92 deletions

View File

@ -739,13 +739,13 @@ p
1019
explain select i from t2 where a='yyyy' and i=3;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref|filter k1,k2 k1|k2 5|11 const 189 (27%) Using where; Using rowid filter
1 SIMPLE t2 ref k1,k2 k1 5 const 189 Using where
select i from t2 where a='yyyy' and i=3;
i
3
explain select a from t2 where a='yyyy' and i=3;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref|filter k1,k2 k1|k2 5|11 const 189 (27%) Using where; Using rowid filter
1 SIMPLE t2 ref k1,k2 k1 5 const 189 Using where
select a from t2 where a='yyyy' and i=3 ;
a
yyyy
@ -753,7 +753,7 @@ select * from information_schema.key_caches where segment_number is null;
KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_BLOCKS DIRTY_BLOCKS READ_REQUESTS READS WRITE_REQUESTS WRITES
default 2 NULL 32768 1024 # # 0 3178 24 1552 18
small NULL NULL 1048576 1024 # # 0 0 0 0 0
keycache1 7 NULL 262143 2048 # # 0 3283 43 1594 30
keycache1 7 NULL 262143 2048 # # 0 3231 43 1594 30
keycache2 NULL NULL 1048576 1024 # # 0 6 6 3 3
set global keycache1.key_cache_block_size=2*1024;
insert into t2 values (7000, 3, 'yyyy');

View File

@ -280,7 +280,7 @@ INSERT INTO t1 VALUES
(33,5),(33,5),(33,5),(33,5),(34,5),(35,5);
EXPLAIN SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a,b a 5 NULL 2 Using index condition; Using where
1 SIMPLE t1 ref|filter a,b b|a 5|5 const 15 (5%) Using where; Using rowid filter
SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
a b
DROP TABLE t1;

View File

@ -3475,13 +3475,13 @@ INSERT INTO t2 VALUES
EXPLAIN
SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition
1 SIMPLE t2 ref c c 5 test.t1.a 2
1 SIMPLE t2 ALL c NULL NULL NULL 18 Using where
1 SIMPLE t1 eq_ref|filter PRIMARY,b PRIMARY|b 4|5 test.t2.c 1 (30%) Using where; Using rowid filter
EXPLAIN
SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6 AND a > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition; Using where
1 SIMPLE t2 ref c c 5 test.t1.a 2
1 SIMPLE t2 ALL c NULL NULL NULL 18 Using where
1 SIMPLE t1 eq_ref|filter PRIMARY,b PRIMARY|b 4|5 test.t2.c 1 (30%) Using where; Using rowid filter
DROP TABLE t1, t2;
create table t1 (
a int unsigned not null auto_increment primary key,

View File

@ -3486,13 +3486,13 @@ INSERT INTO t2 VALUES
EXPLAIN
SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition; Rowid-ordered scan
1 SIMPLE t2 ref c c 5 test.t1.a 2 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
1 SIMPLE t2 ALL c NULL NULL NULL 18 Using where
1 SIMPLE t1 eq_ref|filter PRIMARY,b PRIMARY|b 4|5 test.t2.c 1 (30%) Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan; Using rowid filter
EXPLAIN
SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6 AND a > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition; Using where; Rowid-ordered scan
1 SIMPLE t2 ref c c 5 test.t1.a 2 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
1 SIMPLE t2 ALL c NULL NULL NULL 18 Using where
1 SIMPLE t1 eq_ref|filter PRIMARY,b PRIMARY|b 4|5 test.t2.c 1 (30%) Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan; Using rowid filter
DROP TABLE t1, t2;
create table t1 (
a int unsigned not null auto_increment primary key,

View File

@ -3475,13 +3475,13 @@ INSERT INTO t2 VALUES
EXPLAIN
SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition
1 SIMPLE t2 ref c c 5 test.t1.a 2
1 SIMPLE t2 ALL c NULL NULL NULL 18 Using where
1 SIMPLE t1 eq_ref|filter PRIMARY,b PRIMARY|b 4|5 test.t2.c 1 (30%) Using where; Using rowid filter
EXPLAIN
SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6 AND a > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition; Using where
1 SIMPLE t2 ref c c 5 test.t1.a 2
1 SIMPLE t2 ALL c NULL NULL NULL 18 Using where
1 SIMPLE t1 eq_ref|filter PRIMARY,b PRIMARY|b 4|5 test.t2.c 1 (30%) Using where; Using rowid filter
DROP TABLE t1, t2;
create table t1 (
a int unsigned not null auto_increment primary key,

View File

@ -132,7 +132,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t3.PARENTID 1 Using where
1 PRIMARY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t3.PARENTID 1 Using where
1 PRIMARY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t3.PARENTID 1 Using where
1 PRIMARY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t3.PARENTID 1 Using where
1 PRIMARY t3 ref|filter PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX FFOLDERID_IDX|CMFLDRPARNT_IDX 34|35 test.t3.PARENTID 1 (29%) Using where; Using rowid filter
drop table t1, t2, t3, t4;
CREATE TABLE t1 (a int(10) , PRIMARY KEY (a)) Engine=InnoDB;
INSERT INTO t1 VALUES (1),(2);

View File

@ -1107,11 +1107,11 @@ WHERE alias5.b = alias4.b
AND ( alias5.b >= alias3.b OR alias5.c != alias3.c )
);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL 19
1 PRIMARY alias5 index PRIMARY c 4 NULL 19 Using where; Using index
1 PRIMARY alias4 eq_ref PRIMARY,c PRIMARY 4 test.alias5.b 1 Using where; FirstMatch(alias3)
1 PRIMARY alias1 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join)
1 PRIMARY alias2 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join)
1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL #
1 PRIMARY alias5 index PRIMARY c 4 NULL # Using where; Using index
1 PRIMARY alias4 eq_ref PRIMARY,c PRIMARY 4 test.alias5.b # Using where; FirstMatch(alias3)
1 PRIMARY alias1 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join)
1 PRIMARY alias2 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join)
SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
WHERE alias3.d IN (
SELECT alias4.c FROM t2 AS alias4, t2 AS alias5
@ -1128,11 +1128,11 @@ WHERE alias5.b = alias4.b
AND ( alias5.b >= alias3.b OR alias3.c != alias5.c )
);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL 19
1 PRIMARY alias5 index PRIMARY c 4 NULL 19 Using where; Using index
1 PRIMARY alias4 eq_ref PRIMARY,c PRIMARY 4 test.alias5.b 1 Using where; FirstMatch(alias3)
1 PRIMARY alias1 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join)
1 PRIMARY alias2 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join)
1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL #
1 PRIMARY alias5 index PRIMARY c 4 NULL # Using where; Using index
1 PRIMARY alias4 eq_ref PRIMARY,c PRIMARY 4 test.alias5.b # Using where; FirstMatch(alias3)
1 PRIMARY alias1 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join)
1 PRIMARY alias2 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join)
SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
WHERE alias3.d IN (
SELECT alias4.c FROM t2 AS alias4, t2 AS alias5

View File

@ -1223,6 +1223,7 @@ INSERT INTO t2 VALUES
(13,'b','b'),(14,'x','x'),(15,'g','g'),(16,'p','p'),
(17,'q','q'),(18,'w','w'),(19,'d','d');
--replace_column 9 #
EXPLAIN
SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
WHERE alias3.d IN (
@ -1242,6 +1243,7 @@ WHERE alias3.d IN (
# Do the same EXPLAIN SELECT and SELECT
# with "alias3.c != alias5.c" instead of "alias5.c != alias3.c"
--replace_column 9 #
EXPLAIN
SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
WHERE alias3.d IN (

View File

@ -1123,11 +1123,11 @@ WHERE alias5.b = alias4.b
AND ( alias5.b >= alias3.b OR alias5.c != alias3.c )
);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL 19
1 PRIMARY alias5 index PRIMARY c 4 NULL 19 Using where; Using index; Using join buffer (flat, BNL join)
1 PRIMARY alias4 eq_ref PRIMARY,c PRIMARY 4 test.alias5.b 1 Using where; FirstMatch(alias3); Using join buffer (incremental, BKA join); Key-ordered scan
1 PRIMARY alias1 ALL NULL NULL NULL NULL 14 Using join buffer (incremental, BNL join)
1 PRIMARY alias2 ALL NULL NULL NULL NULL 14 Using join buffer (incremental, BNL join)
1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL #
1 PRIMARY alias5 index PRIMARY c 4 NULL # Using where; Using index; Using join buffer (flat, BNL join)
1 PRIMARY alias4 eq_ref PRIMARY,c PRIMARY 4 test.alias5.b # Using where; FirstMatch(alias3); Using join buffer (incremental, BKA join); Key-ordered scan
1 PRIMARY alias1 ALL NULL NULL NULL NULL # Using join buffer (incremental, BNL join)
1 PRIMARY alias2 ALL NULL NULL NULL NULL # Using join buffer (incremental, BNL join)
SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
WHERE alias3.d IN (
SELECT alias4.c FROM t2 AS alias4, t2 AS alias5
@ -1144,11 +1144,11 @@ WHERE alias5.b = alias4.b
AND ( alias5.b >= alias3.b OR alias3.c != alias5.c )
);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL 19
1 PRIMARY alias5 index PRIMARY c 4 NULL 19 Using where; Using index; Using join buffer (flat, BNL join)
1 PRIMARY alias4 eq_ref PRIMARY,c PRIMARY 4 test.alias5.b 1 Using where; FirstMatch(alias3); Using join buffer (incremental, BKA join); Key-ordered scan
1 PRIMARY alias1 ALL NULL NULL NULL NULL 14 Using join buffer (incremental, BNL join)
1 PRIMARY alias2 ALL NULL NULL NULL NULL 14 Using join buffer (incremental, BNL join)
1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL #
1 PRIMARY alias5 index PRIMARY c 4 NULL # Using where; Using index; Using join buffer (flat, BNL join)
1 PRIMARY alias4 eq_ref PRIMARY,c PRIMARY 4 test.alias5.b # Using where; FirstMatch(alias3); Using join buffer (incremental, BKA join); Key-ordered scan
1 PRIMARY alias1 ALL NULL NULL NULL NULL # Using join buffer (incremental, BNL join)
1 PRIMARY alias2 ALL NULL NULL NULL NULL # Using join buffer (incremental, BNL join)
SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
WHERE alias3.d IN (
SELECT alias4.c FROM t2 AS alias4, t2 AS alias5

View File

@ -1109,11 +1109,11 @@ WHERE alias5.b = alias4.b
AND ( alias5.b >= alias3.b OR alias5.c != alias3.c )
);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL 19
1 PRIMARY alias5 index PRIMARY c 4 NULL 19 Using where; Using index
1 PRIMARY alias4 eq_ref PRIMARY,c PRIMARY 4 test.alias5.b 1 Using where; FirstMatch(alias3)
1 PRIMARY alias1 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join)
1 PRIMARY alias2 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join)
1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL #
1 PRIMARY alias5 index PRIMARY c 4 NULL # Using where; Using index
1 PRIMARY alias4 eq_ref PRIMARY,c PRIMARY 4 test.alias5.b # Using where; FirstMatch(alias3)
1 PRIMARY alias1 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join)
1 PRIMARY alias2 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join)
SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
WHERE alias3.d IN (
SELECT alias4.c FROM t2 AS alias4, t2 AS alias5
@ -1130,11 +1130,11 @@ WHERE alias5.b = alias4.b
AND ( alias5.b >= alias3.b OR alias3.c != alias5.c )
);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL 19
1 PRIMARY alias5 index PRIMARY c 4 NULL 19 Using where; Using index
1 PRIMARY alias4 eq_ref PRIMARY,c PRIMARY 4 test.alias5.b 1 Using where; FirstMatch(alias3)
1 PRIMARY alias1 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join)
1 PRIMARY alias2 ALL NULL NULL NULL NULL 14 Using join buffer (flat, BNL join)
1 PRIMARY alias3 ALL PRIMARY NULL NULL NULL #
1 PRIMARY alias5 index PRIMARY c 4 NULL # Using where; Using index
1 PRIMARY alias4 eq_ref PRIMARY,c PRIMARY 4 test.alias5.b # Using where; FirstMatch(alias3)
1 PRIMARY alias1 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join)
1 PRIMARY alias2 ALL NULL NULL NULL NULL # Using join buffer (flat, BNL join)
SELECT COUNT(*) FROM t1 AS alias1, t1 AS alias2, t2 AS alias3
WHERE alias3.d IN (
SELECT alias4.c FROM t2 AS alias4, t2 AS alias5

View File

@ -6345,7 +6345,7 @@ ha_rows ha_partition::multi_range_read_info(uint keyno, uint n_ranges,
{
uint i;
handler **file;
ha_rows rows;
ha_rows rows= 0;
Cost_estimate part_cost;
DBUG_ENTER("ha_partition::multi_range_read_info");
DBUG_PRINT("enter", ("partition this: %p", this));

View File

@ -49,6 +49,54 @@ double Range_rowid_filter_cost_info::avg_access_and_eval_gain_per_row(
lookup_cost(cont_type);
}
/**
@brief
The average adjusted gain in cost per row of using the filter
@param access_cost_factor the adjusted cost of access a row
@details
The current code to estimate the cost of a ref access is quite inconsistent:
in some cases the effect of page buffers is taken into account, for others
just the engine dependent read_time() is employed. That's why the average
cost of one random seek might differ from 1.
The parameter access_cost_factor can be considered as the cost of a random
seek that is used for the given ref access. Changing the cost of a random
seek we have to change the first coefficient in the linear formula by which
we calculate the gain of usage the given filter for a_adj. This function
calculates the value of a_adj.
@note
Currently we require that access_cost_factor should be a number between
0.0 and 1.0
*/
inline
double Range_rowid_filter_cost_info::avg_adjusted_gain_per_row(
double access_cost_factor)
{
return a - (1 - access_cost_factor) * (1 - selectivity);
}
/**
@brief
Set the parameters used to choose the filter with the best adjusted gain
@note
This function must be called before the call of get_adjusted_gain()
for the given filter.
*/
inline void
Range_rowid_filter_cost_info::set_adjusted_gain_param(double access_cost_factor)
{
a_adj= avg_adjusted_gain_per_row(access_cost_factor);
cross_x_adj= b / a_adj;
}
/**
@brief
Initialize the cost info structure for a range filter
@ -358,6 +406,7 @@ void TABLE::init_cost_info_for_usable_range_rowid_filters(THD *thd)
@param access_key_no The index by which the table is accessed
@param records The estimated total number of key tuples with this access
@param access_cost_factor the cost of a random seek to access the table
@details
The function looks through the array of cost info for range filters
@ -365,8 +414,12 @@ void TABLE::init_cost_info_for_usable_range_rowid_filters(THD *thd)
gain with the the ref or range access of the table by access_key_no.
As the array is sorted by cross_x in ascending order the function stops
the look through as soon as it reaches the first element with
cross_x > records because the range filter for this element and the
range filters for all remaining elements do not promise positive gains
cross_x_adj > records because the range filter for this element and the
range filters for all remaining elements do not promise positive gains.
@note
It is easy to see that if cross_x[i] > cross_x[j] then
cross_x_adj[i] > cross_x_adj[j]
@retval Pointer to the cost info for the range filter that promises
the greatest gain, NULL if there is no such range filter
@ -374,7 +427,8 @@ void TABLE::init_cost_info_for_usable_range_rowid_filters(THD *thd)
Range_rowid_filter_cost_info *
TABLE::best_range_rowid_filter_for_partial_join(uint access_key_no,
double records)
double records,
double access_cost_factor)
{
if (!this || range_rowid_filter_cost_info_elems == 0 ||
covering_keys.is_set(access_key_no))
@ -408,13 +462,15 @@ TABLE::best_range_rowid_filter_for_partial_join(uint access_key_no,
no_filter_usage.is_set(filter->key_no))
continue;
if (records < filter->cross_x)
filter->set_adjusted_gain_param(access_cost_factor);
if (records < filter->cross_x_adj)
{
/* Does not make sense to look through the remaining filters */
break;
}
curr_gain= filter->get_gain(records);
curr_gain= filter->get_adjusted_gain(records);
if (best_filter_gain < curr_gain)
{
best_filter_gain= curr_gain;

View File

@ -396,6 +396,13 @@ class Range_rowid_filter_cost_info : public Sql_alloc
/* Used for pruning of the potential range filters */
key_map abs_independent;
/*
These two parameters are used to choose the best range filter
in the function TABLE::best_range_rowid_filter_for_partial_join
*/
double a_adj;
double cross_x_adj;
public:
/* The type of the container of the range filter */
Rowid_filter_container_type container_type;
@ -416,30 +423,29 @@ public:
inline double
avg_access_and_eval_gain_per_row(Rowid_filter_container_type cont_type);
/* Get the gain that usage of filter promises for 'rows' key tuples */
inline double get_gain(double rows)
inline double avg_adjusted_gain_per_row(double access_cost_factor);
inline void set_adjusted_gain_param(double access_cost_factor);
/* Get the gain that usage of filter promises for r key tuples */
inline double get_gain(double r)
{
return rows * a - b;
return r * a - b;
}
/* Get the adjusted gain that usage of filter promises for r key tuples */
inline double get_adjusted_gain(double r)
{
return r * a_adj - b;
}
/*
The gain promised by usage of the filter at the assumption that
when the table is accessed without the filter at most worst_seeks
pages are fetched from disk to access the data rows of the table
*/
inline double get_adjusted_gain(double rows, double worst_seeks)
{
return get_gain(rows) -
(1 - selectivity) * (rows - MY_MIN(rows, worst_seeks));
}
/*
The gain promised by usage of the filter
The gain promised by usage of the filter for r key tuples
due to less condition evaluations
*/
inline double get_cmp_gain(double rows)
inline double get_cmp_gain(double r)
{
return rows * (1 - selectivity) / TIME_FOR_COMPARE;
return r * (1 - selectivity) / TIME_FOR_COMPARE;
}
Rowid_filter_container *create_container();
@ -455,7 +461,8 @@ public:
friend
Range_rowid_filter_cost_info *
TABLE::best_range_rowid_filter_for_partial_join(uint access_key_no,
double records);
double records,
double access_cost_factor);
};
#endif /* ROWID_FILTER_INCLUDED */

View File

@ -6981,6 +6981,7 @@ best_access_path(JOIN *join,
KEYUSE *hj_start_key= 0;
SplM_plan_info *spl_plan= 0;
Range_rowid_filter_cost_info *filter= 0;
double filter_cmp_gain= 0;
disable_jbuf= disable_jbuf || idx == join->const_tables;
@ -7376,12 +7377,14 @@ best_access_path(JOIN *join,
if (records < DBL_MAX)
{
double rows= record_count * records;
double access_cost_factor= MY_MIN(tmp / rows, 1.0);
filter=
table->best_range_rowid_filter_for_partial_join(start_key->key, rows);
table->best_range_rowid_filter_for_partial_join(start_key->key, rows,
access_cost_factor);
if (filter)
{
tmp-= filter->get_adjusted_gain(rows, s->worst_seeks) -
filter->get_cmp_gain(rows);
filter->get_cmp_gain(rows);
tmp-= filter->get_adjusted_gain(rows) - filter->get_cmp_gain(rows);
DBUG_ASSERT(tmp >= 0);
}
}
@ -7508,12 +7511,14 @@ best_access_path(JOIN *join,
if ( s->quick->get_type() == QUICK_SELECT_I::QS_TYPE_RANGE)
{
double rows= record_count * s->found_records;
double access_cost_factor= MY_MIN(tmp / rows, 1.0);
uint key_no= s->quick->index;
filter= s->table->best_range_rowid_filter_for_partial_join(key_no,
rows);
filter=
s->table->best_range_rowid_filter_for_partial_join(key_no, rows,
access_cost_factor);
if (filter)
{
tmp-= filter->get_gain(rows);
tmp-= filter->get_adjusted_gain(rows);
DBUG_ASSERT(tmp >= 0);
}
}
@ -7556,7 +7561,6 @@ best_access_path(JOIN *join,
}
}
double best_records= rnd_records;
/* Splitting technique cannot be used with join cache */
if (s->table->is_splittable())
tmp+= s->table->get_materialization_cost();
@ -7569,28 +7573,32 @@ best_access_path(JOIN *join,
tmp give us total cost of using TABLE SCAN
*/
double filter_cmp_gain= 0;
if (filter)
double best_filter_cmp_gain= 0;
if (best_filter)
{
filter_cmp_gain= filter->get_cmp_gain(record_count * s->found_records);
best_filter_cmp_gain= best_filter->get_cmp_gain(record_count * records);
}
if (best == DBL_MAX ||
(tmp + record_count/(double) TIME_FOR_COMPARE*rnd_records <
(best_key->is_for_hash_join() ? best_time :
best + record_count/(double) TIME_FOR_COMPARE*records -
filter_cmp_gain)))
best_filter_cmp_gain)))
{
/*
If the table has a range (s->quick is set) make_join_select()
will ensure that this will be used
*/
best= tmp;
records= best_records;
records= rnd_records;
best_key= 0;
best_filter= 0;
if (s->quick && s->quick->get_type() == QUICK_SELECT_I::QS_TYPE_RANGE)
if (s->quick && s->quick->get_type() == QUICK_SELECT_I::QS_TYPE_RANGE &&
filter)
{
best_filter= filter;
best_filter_cmp_gain= filter_cmp_gain;
}
/* range/index_merge/ALL/index access method are "independent", so: */
best_ref_depends_map= 0;
best_uses_jbuf= MY_TEST(!disable_jbuf && !((s->table->map &
@ -8091,14 +8099,22 @@ optimize_straight_join(JOIN *join, table_map join_tables)
for (JOIN_TAB **pos= join->best_ref + idx ; (s= *pos) ; pos++)
{
/* Find the best access method from 's' to the current partial plan */
POSITION *position= join->positions + idx;
/* Find the best access method from 's' to the current partial plan */
best_access_path(join, s, join_tables, idx, disable_jbuf, record_count,
join->positions + idx, &loose_scan_pos);
position, &loose_scan_pos);
/* compute the cost of the new plan extended with 's' */
record_count*= join->positions[idx].records_read;
read_time+= join->positions[idx].read_time +
record_count / (double) TIME_FOR_COMPARE;
record_count*= position->records_read;
double filter_cmp_gain= 0;
if (position->range_rowid_filter_info)
{
filter_cmp_gain=
position->range_rowid_filter_info->get_cmp_gain(record_count);
}
read_time+= position->read_time +
record_count / (double) TIME_FOR_COMPARE -
filter_cmp_gain;
advance_sj_state(join, join_tables, idx, &record_count, &read_time,
&loose_scan_pos);
@ -8107,7 +8123,7 @@ optimize_straight_join(JOIN *join, table_map join_tables)
if (use_cond_selectivity > 1)
pushdown_cond_selectivity= table_cond_selectivity(join, idx, s,
join_tables);
join->positions[idx].cond_selectivity= pushdown_cond_selectivity;
position->cond_selectivity= pushdown_cond_selectivity;
++idx;
}
@ -9006,8 +9022,15 @@ best_extension_by_limited_search(JOIN *join,
current_record_count= record_count * position->records_read;
else
current_record_count= DBL_MAX;
double filter_cmp_gain= 0;
if (position->range_rowid_filter_info)
{
filter_cmp_gain=
position->range_rowid_filter_info->get_cmp_gain(current_record_count);
}
current_read_time=read_time + position->read_time +
current_record_count / (double) TIME_FOR_COMPARE;
current_record_count / (double) TIME_FOR_COMPARE -
filter_cmp_gain;
advance_sj_state(join, remaining_tables, idx, &current_record_count,
&current_read_time, &loose_scan_pos);

View File

@ -1524,7 +1524,8 @@ public:
void prune_range_rowid_filters();
Range_rowid_filter_cost_info *
best_range_rowid_filter_for_partial_join(uint access_key_no,
double records);
double records,
double access_cost_factor);
/**
System Versioning support