summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVarun Gupta <varun.gupta@mariadb.com>2020-06-04 19:38:31 +0530
committerVarun Gupta <varun.gupta@mariadb.com>2020-06-04 20:03:22 +0530
commit6404645980db51fdc1e5dae2ac94eca57804284b (patch)
treecff554f81b79db94889a274befe26ed658a4735b
parent80591481549213f5701642e682cc2974b60c53dd (diff)
downloadmariadb-git-6404645980db51fdc1e5dae2ac94eca57804284b.tar.gz
MDEV-21626: Optimizer misses the details about the picked join order
Added cost of sorting estimate to the optimizer trace
-rw-r--r--mysql-test/main/opt_trace.result173
-rw-r--r--mysql-test/main/opt_trace.test15
-rw-r--r--sql/sql_select.cc3
3 files changed, 191 insertions, 0 deletions
diff --git a/mysql-test/main/opt_trace.result b/mysql-test/main/opt_trace.result
index f43290651f9..be358e69c47 100644
--- a/mysql-test/main/opt_trace.result
+++ b/mysql-test/main/opt_trace.result
@@ -441,6 +441,7 @@ select * from v2 {
},
"rows_for_plan": 1,
"cost_for_plan": 2.4044,
+ "cost_for_sorting": 1,
"estimated_join_cardinality": 1
}
]
@@ -765,6 +766,7 @@ explain select * from v1 {
},
"rows_for_plan": 10,
"cost_for_plan": 4.022,
+ "cost_for_sorting": 10,
"estimated_join_cardinality": 10
}
]
@@ -1449,6 +1451,7 @@ EXPLAIN SELECT MIN(d) FROM t1 where b=2 and c=3 group by a {
},
"rows_for_plan": 0.5849,
"cost_for_plan": 3.4291,
+ "cost_for_sorting": 0.5849,
"estimated_join_cardinality": 0.5849
}
]
@@ -1650,6 +1653,7 @@ EXPLAIN SELECT id,MIN(a),MAX(a) FROM t1 WHERE a>=20010104e0 GROUP BY id {
},
"rows_for_plan": 16,
"cost_for_plan": 5.2313,
+ "cost_for_sorting": 16,
"estimated_join_cardinality": 16
}
]
@@ -1840,6 +1844,7 @@ EXPLAIN SELECT * FROM t1 WHERE a = 20010104e0 GROUP BY id {
},
"rows_for_plan": 16,
"cost_for_plan": 5.2313,
+ "cost_for_sorting": 16,
"estimated_join_cardinality": 16
}
]
@@ -8292,5 +8297,173 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.range_scan_alternatives'))
]
]
drop table t1;
+#
+# MDEV-21626: Optimizer misses the details about the picked join order
+#
+CREATE TABLE t1(a INT, b INT, key(a));
+INSERT INTO t1 SELECT seq, seq from seq_1_to_10;
+CREATE TABLE t2(a INT, b INT, key(a));
+INSERT INTO t2 SELECT seq, seq from seq_1_to_100;
+SET OPTIMIZER_TRACE=1;
+EXPLAIN SELECT * FROM t1, t2 WHERE t1.a=t2.a ORDER BY t2.b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL a NULL NULL NULL 10 Using where; Using temporary; Using filesort
+1 SIMPLE t2 ref a a 5 test.t1.a 1
+select JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans'))
+[
+
+ [
+
+ {
+ "plan_prefix":
+ [
+ ],
+ "table": "t1",
+ "best_access_path":
+ {
+ "considered_access_paths":
+ [
+
+ {
+ "access_type": "scan",
+ "resulting_rows": 10,
+ "cost": 2.022,
+ "chosen": true
+ }
+ ],
+ "chosen_access_method":
+ {
+ "type": "scan",
+ "records": 10,
+ "cost": 2.022,
+ "uses_join_buffering": false
+ }
+ },
+ "rows_for_plan": 10,
+ "cost_for_plan": 4.022,
+ "rest_of_plan":
+ [
+
+ {
+ "plan_prefix":
+ [
+ "t1"
+ ],
+ "table": "t2",
+ "best_access_path":
+ {
+ "considered_access_paths":
+ [
+
+ {
+ "access_type": "ref",
+ "index": "a",
+ "used_range_estimates": false,
+ "cause": "not available",
+ "rows": 1,
+ "cost": 20,
+ "chosen": true
+ },
+
+ {
+ "access_type": "scan",
+ "resulting_rows": 100,
+ "cost": 2.2197,
+ "chosen": false
+ }
+ ],
+ "chosen_access_method":
+ {
+ "type": "ref",
+ "records": 1,
+ "cost": 20,
+ "uses_join_buffering": false
+ }
+ },
+ "rows_for_plan": 10,
+ "cost_for_plan": 26.022,
+ "cost_for_sorting": 10,
+ "estimated_join_cardinality": 10
+ }
+ ]
+ },
+
+ {
+ "plan_prefix":
+ [
+ ],
+ "table": "t2",
+ "best_access_path":
+ {
+ "considered_access_paths":
+ [
+
+ {
+ "access_type": "scan",
+ "resulting_rows": 100,
+ "cost": 2.2197,
+ "chosen": true,
+ "use_tmp_table": true
+ }
+ ],
+ "chosen_access_method":
+ {
+ "type": "scan",
+ "records": 100,
+ "cost": 2.2197,
+ "uses_join_buffering": false
+ }
+ },
+ "rows_for_plan": 100,
+ "cost_for_plan": 22.22,
+ "rest_of_plan":
+ [
+
+ {
+ "plan_prefix":
+ [
+ "t2"
+ ],
+ "table": "t1",
+ "best_access_path":
+ {
+ "considered_access_paths":
+ [
+
+ {
+ "access_type": "ref",
+ "index": "a",
+ "used_range_estimates": false,
+ "cause": "not available",
+ "rows": 1,
+ "cost": 200,
+ "chosen": true
+ },
+
+ {
+ "access_type": "scan",
+ "resulting_rows": 10,
+ "cost": 2.022,
+ "chosen": true
+ }
+ ],
+ "chosen_access_method":
+ {
+ "type": "scan",
+ "records": 10,
+ "cost": 2.022,
+ "uses_join_buffering": true
+ }
+ },
+ "rows_for_plan": 1000,
+ "cost_for_plan": 224.24,
+ "pruned_by_cost": true
+ }
+ ]
+ }
+ ]
+]
+DROP TABLE t1,t2;
# End of 10.4 tests
set optimizer_trace='enabled=off';
diff --git a/mysql-test/main/opt_trace.test b/mysql-test/main/opt_trace.test
index 712c58dd2d3..d1a8fedc635 100644
--- a/mysql-test/main/opt_trace.test
+++ b/mysql-test/main/opt_trace.test
@@ -1,4 +1,5 @@
--source include/not_embedded.inc
+--source include/have_sequence.inc
SELECT table_name, column_name FROM information_schema.columns where table_name="OPTIMIZER_TRACE";
show variables like 'optimizer_trace';
set optimizer_trace="enabled=on";
@@ -579,6 +580,20 @@ select * from t1 force index(kp1) where (kp1=2 and kp2 >=4);
select JSON_DETAILED(JSON_EXTRACT(trace, '$**.range_scan_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
drop table t1;
+--echo #
+--echo # MDEV-21626: Optimizer misses the details about the picked join order
+--echo #
+
+CREATE TABLE t1(a INT, b INT, key(a));
+INSERT INTO t1 SELECT seq, seq from seq_1_to_10;
+CREATE TABLE t2(a INT, b INT, key(a));
+INSERT INTO t2 SELECT seq, seq from seq_1_to_100;
+
+SET OPTIMIZER_TRACE=1;
+EXPLAIN SELECT * FROM t1, t2 WHERE t1.a=t2.a ORDER BY t2.b;
+select JSON_DETAILED(JSON_EXTRACT(trace, '$**.considered_execution_plans')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
+DROP TABLE t1,t2;
+
--echo # End of 10.4 tests
set optimizer_trace='enabled=off';
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 568a3ed6062..040c9acd2ae 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -9593,12 +9593,15 @@ best_extension_by_limited_search(JOIN *join,
if (join->sort_by_table &&
join->sort_by_table !=
join->positions[join->const_tables].table->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.
*/
+ trace_one_table.add("cost_for_sorting", current_record_count);
current_read_time= COST_ADD(current_read_time, current_record_count);
+ }
trace_one_table.add("estimated_join_cardinality",
partial_join_cardinality);
if (current_read_time < join->best_read)