Skip to content
/ server Public
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions mysql-test/main/mdev-38877.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#
# MDEV-38877: Unnecessary filesort on derived table materialization
# when derived table is inherently sorted by the grouping columns
#
CREATE TABLE t1 (
groups_20 int NOT NULL,
groups_20_2 int NOT NULL,
b int,
PRIMARY KEY (groups_20, groups_20_2)
);
CREATE TABLE t2 (a int, b int, index(a));
INSERT INTO t1 SELECT seq/1000, seq+1, seq from seq_1_to_10000;
INSERT INTO t2 SELECT seq, seq from seq_1_to_1000;
ANALYZE TABLE t1, t2;
EXPLAIN
SELECT
a,
SUM(b)
FROM (
SELECT
groups_20
FROM t1
GROUP BY groups_20
HAVING COUNT(*) != 1000
) DT
JOIN t2 ON a = groups_20
GROUP BY a;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL a NULL NULL NULL 1000 Using where; Using temporary; Using filesort
1 PRIMARY <derived2> ref key0 key0 4 test.t2.a 1
2 DERIVED t1 index PRIMARY PRIMARY 8 NULL 10000 Using index
DROP TABLE t1, t2;
39 changes: 39 additions & 0 deletions mysql-test/main/mdev-38877.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
--source include/have_sequence.inc

--echo #
--echo # MDEV-38877: Unnecessary filesort on derived table materialization
--echo # when derived table is inherently sorted by the grouping columns
--echo #

CREATE TABLE t1 (
groups_20 int NOT NULL,
groups_20_2 int NOT NULL,
b int,
PRIMARY KEY (groups_20, groups_20_2)
);

CREATE TABLE t2 (a int, b int, index(a));

--disable_result_log
INSERT INTO t1 SELECT seq/1000, seq+1, seq from seq_1_to_10000;

INSERT INTO t2 SELECT seq, seq from seq_1_to_1000;

ANALYZE TABLE t1, t2;
--enable_result_log

EXPLAIN
SELECT
a,
SUM(b)
FROM (
SELECT
groups_20
FROM t1
GROUP BY groups_20
HAVING COUNT(*) != 1000
) DT
JOIN t2 ON a = groups_20
GROUP BY a;

DROP TABLE t1, t2;
17 changes: 15 additions & 2 deletions sql/sql_select.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7916,7 +7916,21 @@ bool sort_and_filter_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse,
{
if (!(use->used_tables & ~OUTER_REF_TABLE_BIT) &&
use->optimize != KEY_OPTIMIZE_REF_OR_NULL)
use->table->const_key_parts[use->key]|= use->keypart_map;
{
TABLE_LIST *derived_table= use->table->pos_in_table_list;
if (derived_table && derived_table->select_lex)
{
st_select_lex_unit *master_unit=
derived_table->select_lex->master_unit();
if (master_unit)
derived_table= master_unit->derived;
}
// derived tables shouldn't treat outer
// references as constants
if (!(derived_table && derived_table->is_materialized_derived()) ||
use->used_tables == 0)
use->table->const_key_parts[use->key]|= use->keypart_map;
}
if (use->keypart != FT_KEYPART)
{
if (use->key == prev->key && use->table == prev->table)
Expand Down Expand Up @@ -27562,7 +27576,6 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
*fatal_error= false;
/* Check that we are always called with first non-const table */
DBUG_ASSERT(tab == tab->join->join_tab + tab->join->const_tables);

/* Sorting a single row can always be skipped */
if (tab->type == JT_EQ_REF ||
tab->type == JT_CONST ||
Expand Down
Loading