mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
MDEV-5846 MySQL Bug #18144 - Cost with FORCE/USE index seems incorrect in some cases.
This commit is contained in:
@ -612,3 +612,30 @@ SELECT 1 as RES FROM t1 AS t1_outer WHERE
|
|||||||
(SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) > 12;
|
(SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) > 12;
|
||||||
RES
|
RES
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# Bug#18144: Cost with FORCE/USE index seems incorrect in some cases.
|
||||||
|
#
|
||||||
|
# We are interested in showing that the cost for the last plan is higher
|
||||||
|
# than for the preceding two plans.
|
||||||
|
#
|
||||||
|
CREATE TABLE t1( a INT, b INT, KEY( a ) );
|
||||||
|
INSERT INTO t1 values (1, 2), (1, 3), (2, 3), (2, 4), (3, 4), (3, 5);
|
||||||
|
EXPLAIN SELECT a, SUM( b ) FROM t1 GROUP BY a;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort
|
||||||
|
SHOW STATUS LIKE 'Last_query_cost';
|
||||||
|
Variable_name Value
|
||||||
|
Last_query_cost 9.212184
|
||||||
|
EXPLAIN SELECT a, SUM( b ) FROM t1 USE INDEX( a ) GROUP BY a;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort
|
||||||
|
SHOW STATUS LIKE 'Last_query_cost';
|
||||||
|
Variable_name Value
|
||||||
|
Last_query_cost 9.212184
|
||||||
|
EXPLAIN SELECT a, SUM( b ) FROM t1 FORCE INDEX( a ) GROUP BY a;
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 index NULL a 5 NULL 6
|
||||||
|
SHOW STATUS LIKE 'Last_query_cost';
|
||||||
|
Variable_name Value
|
||||||
|
Last_query_cost 14.199000
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -561,3 +561,23 @@ SELECT 1 as RES FROM t1 AS t1_outer WHERE
|
|||||||
(SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) > 12;
|
(SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) > 12;
|
||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug#18144: Cost with FORCE/USE index seems incorrect in some cases.
|
||||||
|
--echo #
|
||||||
|
--echo # We are interested in showing that the cost for the last plan is higher
|
||||||
|
--echo # than for the preceding two plans.
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE t1( a INT, b INT, KEY( a ) );
|
||||||
|
INSERT INTO t1 values (1, 2), (1, 3), (2, 3), (2, 4), (3, 4), (3, 5);
|
||||||
|
|
||||||
|
EXPLAIN SELECT a, SUM( b ) FROM t1 GROUP BY a;
|
||||||
|
SHOW STATUS LIKE 'Last_query_cost';
|
||||||
|
|
||||||
|
EXPLAIN SELECT a, SUM( b ) FROM t1 USE INDEX( a ) GROUP BY a;
|
||||||
|
SHOW STATUS LIKE 'Last_query_cost';
|
||||||
|
|
||||||
|
EXPLAIN SELECT a, SUM( b ) FROM t1 FORCE INDEX( a ) GROUP BY a;
|
||||||
|
SHOW STATUS LIKE 'Last_query_cost';
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -2721,6 +2721,18 @@ public:
|
|||||||
}
|
}
|
||||||
virtual double scan_time()
|
virtual double scan_time()
|
||||||
{ return ulonglong2double(stats.data_file_length) / IO_SIZE + 2; }
|
{ return ulonglong2double(stats.data_file_length) / IO_SIZE + 2; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
The cost of reading a set of ranges from the table using an index
|
||||||
|
to access it.
|
||||||
|
|
||||||
|
@param index The index number.
|
||||||
|
@param ranges The number of ranges to be read.
|
||||||
|
@param rows Total number of rows to be read.
|
||||||
|
|
||||||
|
This method can be used to calculate the total cost of scanning a table
|
||||||
|
using an index by calling it using read_time(index, 1, table_size).
|
||||||
|
*/
|
||||||
virtual double read_time(uint index, uint ranges, ha_rows rows)
|
virtual double read_time(uint index, uint ranges, ha_rows rows)
|
||||||
{ return rows2double(ranges+rows); }
|
{ return rows2double(ranges+rows); }
|
||||||
|
|
||||||
|
@ -6158,7 +6158,11 @@ best_access_path(JOIN *join,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Estimate cost of reading table. */
|
/* Estimate cost of reading table. */
|
||||||
tmp= s->scan_time();
|
if (s->table->force_index && !best_key) // index scan
|
||||||
|
tmp= s->table->file->read_time(s->ref.key, 1, s->records);
|
||||||
|
else // table scan
|
||||||
|
tmp= s->scan_time();
|
||||||
|
|
||||||
if ((s->table->map & join->outer_join) || disable_jbuf) // Can't use join cache
|
if ((s->table->map & join->outer_join) || disable_jbuf) // Can't use join cache
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -7611,7 +7615,11 @@ best_extension_by_limited_search(JOIN *join,
|
|||||||
if (join->sort_by_table &&
|
if (join->sort_by_table &&
|
||||||
join->sort_by_table !=
|
join->sort_by_table !=
|
||||||
join->positions[join->const_tables].table->table)
|
join->positions[join->const_tables].table->table)
|
||||||
/* We have to make a temp table */
|
/*
|
||||||
|
We may have to make a temp table, note that this is only a
|
||||||
|
heuristic since we cannot know for sure at this point.
|
||||||
|
Hence it may be wrong.
|
||||||
|
*/
|
||||||
current_read_time+= current_record_count;
|
current_read_time+= current_record_count;
|
||||||
if (current_read_time < join->best_read)
|
if (current_read_time < join->best_read)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user