Commit d0f2efc0 authored by Igor Babaev's avatar Igor Babaev

Fixed LP bug #917990.

If the expression for a derived table of a query contained a LIMIT
clause the estimate of the number of rows in this derived table
returned by the EXPLAIN command could be badly off since the
optimizer ignored the limit number from the LIMIT clause when
getting the estimate. 
The call of the method SELECT_LEX_UNIT->set_limit added in the code
of mysql_derived_optimize() will be needed also in maria-5.5 where
parameters in the LIMIT clause are supported. 
parent f5fa257e
......@@ -1879,5 +1879,22 @@ ORDER BY CONCAT(alias2.col_varchar_nokey);
col_varchar_key pk col_varchar_key col_varchar_nokey
set max_heap_table_size= @tmp_882994;
drop table t1,t2,t3;
#
# LP bug #917990: Bad estimate of #rows for derived table with LIMIT
#
CREATE TABLE t1 (a int);
INSERT INTO t1 VALUES
(8), (3), (4), (7), (9), (5), (1), (2);
SELECT * FROM (SELECT * FROM t1 LIMIT 3) t;
a
8
3
4
EXPLAIN
SELECT * FROM (SELECT * FROM t1 LIMIT 3) t;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 3
2 DERIVED t1 ALL NULL NULL NULL NULL 8
DROP TABLE t1;
set optimizer_switch=@exit_optimizer_switch;
set join_cache_level=@exit_join_cache_level;
......@@ -304,7 +304,7 @@ a+1
4
explain select * from v1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort
drop view v1;
drop table t1;
......
......@@ -107,7 +107,7 @@ MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1.
MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
explain select * from v1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort
drop view v1;
create view v1 as select c+1 from t1 order by 1 desc limit 2;
......@@ -119,7 +119,7 @@ MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1.
MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
explain select * from v1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort
drop view v1;
drop table t1;
......
......@@ -107,7 +107,7 @@ MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1.
MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
explain select * from v1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort
drop view v1;
create view v1 as select c+1 from t1 order by 1 desc limit 2;
......@@ -119,7 +119,7 @@ MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1.
MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
explain select * from v1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using filesort
drop view v1;
drop table t1;
......
......@@ -1277,6 +1277,20 @@ ORDER BY CONCAT(alias2.col_varchar_nokey);
set max_heap_table_size= @tmp_882994;
drop table t1,t2,t3;
--echo #
--echo # LP bug #917990: Bad estimate of #rows for derived table with LIMIT
--echo #
CREATE TABLE t1 (a int);
INSERT INTO t1 VALUES
(8), (3), (4), (7), (9), (5), (1), (2);
SELECT * FROM (SELECT * FROM t1 LIMIT 3) t;
EXPLAIN
SELECT * FROM (SELECT * FROM t1 LIMIT 3) t;
DROP TABLE t1;
# The following command must be the last one the file
set optimizer_switch=@exit_optimizer_switch;
set join_cache_level=@exit_join_cache_level;
......@@ -753,6 +753,7 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived)
if (!derived->is_merged_derived())
{
JOIN *join= first_select->join;
unit->set_limit(first_select);
unit->optimized= TRUE;
if ((res= join->optimize()))
goto err;
......
......@@ -3581,6 +3581,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
for (i= 0; i < join->table_count ; i++)
records*= join->best_positions[i].records_read ?
(ha_rows)join->best_positions[i].records_read : 1;
set_if_smaller(records, unit->select_limit_cnt);
join->select_lex->increase_derived_records(records);
}
}
......
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