summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Petrunia <psergey@askmonty.org>2014-11-27 23:10:44 +0300
committerSergei Petrunia <psergey@askmonty.org>2014-11-27 23:10:44 +0300
commit461dbd80d2ea96034f330dd238282d2167ed2c4d (patch)
tree814c5063aeecce0af411b9bc2d85df520bd62f15
parent37c444e1a079b25d0a34efbbc2fadfae17999966 (diff)
downloadmariadb-git-461dbd80d2ea96034f330dd238282d2167ed2c4d.tar.gz
EXPLAIN FORMAT=JSON: support join buffering
- Basic support for JOIN buffering - The output is not polished but catches the main point: tab->select_cond and tab->cache_select->cond are printed separately. - Hash join support is poor still. - Also fixed identation in JOIN_TAB::save_explain_data
-rw-r--r--mysql-test/r/explain_json.result33
-rw-r--r--mysql-test/t/explain_json.test12
-rw-r--r--sql/sql_explain.cc39
-rw-r--r--sql/sql_explain.h11
-rw-r--r--sql/sql_select.cc14
5 files changed, 97 insertions, 12 deletions
diff --git a/mysql-test/r/explain_json.result b/mysql-test/r/explain_json.result
index d2225c1e189..ec775c8d618 100644
--- a/mysql-test/r/explain_json.result
+++ b/mysql-test/r/explain_json.result
@@ -309,4 +309,37 @@ EXPLAIN
}
}
drop table t1;
+#
+# Join buffering
+#
+create table t1 (a int, b int);
+insert into t1 select A.a+10*B.a, A.a+10*B.a from t0 A, t0 B;
+explain format=json
+select * from t1 A, t1 B where A.a=B.a and A.b < 3 and B.b < 5;
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "A",
+ "access_type": "ALL",
+ "rows": 100,
+ "filtered": 100,
+ "attached_condition": "(A.b < 3)"
+ },
+ "block-nl-join": {
+ "table": {
+ "table_name": "B",
+ "access_type": "ALL",
+ "rows": 100,
+ "filtered": 100,
+ "attached_condition": "(B.b < 5)"
+ },
+ "buffer_type": "flat",
+ "join_type": "BNL",
+ "attached_condition": "(B.a = A.a)"
+ }
+ }
+}
+drop table t1;
drop table t0;
diff --git a/mysql-test/t/explain_json.test b/mysql-test/t/explain_json.test
index 32932e0ff69..6dc54f1492b 100644
--- a/mysql-test/t/explain_json.test
+++ b/mysql-test/t/explain_json.test
@@ -58,5 +58,17 @@ select * from t0 where
a > (select max(b) from t1 where t1.b=t0.a) or a < 3 ;
drop table t1;
+
+--echo #
+--echo # Join buffering
+--echo #
+create table t1 (a int, b int);
+insert into t1 select A.a+10*B.a, A.a+10*B.a from t0 A, t0 B;
+
+explain format=json
+select * from t1 A, t1 B where A.a=B.a and A.b < 3 and B.b < 5;
+
+drop table t1;
+
drop table t0;
diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc
index 2e60c65aa2e..a37d324180f 100644
--- a/sql/sql_explain.cc
+++ b/sql/sql_explain.cc
@@ -903,8 +903,18 @@ void Explain_table_access::tag_to_json(Json_writer *writer, enum explain_extra_t
write_item(writer, pushed_index_cond);
break;
case ET_USING_WHERE:
- writer->add_member("attached_condition");
- write_item(writer, where_cond);
+ if (where_cond)
+ {
+ writer->add_member("attached_condition");
+ /*
+ We are printing the condition that is checked when scanning this
+ table.
+ - when join buffer is used, it is cache_cond.
+ - in other cases, it is where_cond.
+ */
+ Item *item= bka_type.is_using_jbuf()? cache_cond: where_cond;
+ write_item(writer, item);
+ }
break;
case ET_USING_INDEX:
writer->add_member("using_index").add_bool(true);
@@ -912,8 +922,8 @@ void Explain_table_access::tag_to_json(Json_writer *writer, enum explain_extra_t
case ET_USING:
// index merge: case ET_USING
break;
- case ET_USING_JOIN_BUFFER:
- // TODO TODO
+ case ET_USING_JOIN_BUFFER:
+ /* Do nothing. Join buffer is handled differently */
break;
default:
DBUG_ASSERT(0);
@@ -925,6 +935,12 @@ void Explain_table_access::print_explain_json(Json_writer *writer,
bool is_analyze)
{
Json_writer_nesting_guard guard(writer);
+
+ if (bka_type.is_using_jbuf())
+ {
+ writer->add_member("block-nl-join").start_object();
+ }
+
writer->add_member("table").start_object();
writer->add_member("table_name").add_str(table_name);
@@ -1018,6 +1034,21 @@ void Explain_table_access::print_explain_json(Json_writer *writer,
tag_to_json(writer, extra_tags.at(i));
}
+ if (bka_type.is_using_jbuf())
+ {
+ writer->end_object();
+ writer->add_member("buffer_type").add_str(bka_type.incremental?
+ "incremental":"flat");
+ writer->add_member("join_type").add_str(bka_type.join_alg);
+ if (bka_type.mrr_type.length())
+ writer->add_member("mrr_type").add_str(bka_type.mrr_type);
+ if (where_cond)
+ {
+ writer->add_member("attached_condition");
+ write_item(writer, where_cond);
+ }
+ }
+
writer->end_object();
}
diff --git a/sql/sql_explain.h b/sql/sql_explain.h
index 39392d370d9..6cc8e012a95 100644
--- a/sql/sql_explain.h
+++ b/sql/sql_explain.h
@@ -488,6 +488,12 @@ private:
class Explain_table_access : public Sql_alloc
{
public:
+ Explain_table_access() :
+ where_cond(NULL),
+ cache_cond(NULL),
+ pushed_index_cond(NULL)
+ {}
+
void push_extra(enum explain_extra_tag extra_tag);
/* Internals */
@@ -558,9 +564,12 @@ public:
/*
Note: lifespan of WHERE condition is less than lifespan of this object.
- THe below is valid if tags include "ET_USING_WHERE".
+ The below two are valid if tags include "ET_USING_WHERE".
+ (TODO: indexsubquery may put ET_USING_WHERE without setting where_cond?)
*/
Item *where_cond;
+ Item *cache_cond;
+
Item *pushed_index_cond;
int print_explain(select_result_sink *output, uint8 explain_flags,
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 96feb2b0f3d..185c0929670 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -23650,10 +23650,10 @@ void JOIN_TAB::save_explain_data(Explain_table_access *eta, table_map prefix_tab
if (keyno != MAX_KEY && keyno == table->file->pushed_idx_cond_keyno &&
table->file->pushed_idx_cond)
- {
+ {
eta->push_extra(ET_USING_INDEX_CONDITION);
- eta->pushed_index_cond= table->file->pushed_idx_cond;
- }
+ eta->pushed_index_cond= table->file->pushed_idx_cond;
+ }
else if (tab->cache_idx_cond)
eta->push_extra(ET_USING_INDEX_CONDITION_BKA);
@@ -23683,11 +23683,11 @@ void JOIN_TAB::save_explain_data(Explain_table_access *eta, table_map prefix_tab
eta->push_extra(ET_USING_WHERE_WITH_PUSHED_CONDITION);
}
else
- {
- eta->where_cond= tab->select->cond? tab->select->cond:
- tab->cache_select->cond;
+ {
+ eta->where_cond= tab->select->cond;
+ eta->cache_cond= tab->cache_select? tab->cache_select->cond : NULL;
eta->push_extra(ET_USING_WHERE);
- }
+ }
}
}
if (table_list /* SJM bushes don't have table_list */ &&