Skip to content

Instantly share code, notes, and snippets.

@spetrunia
Created July 8, 2024 12:37
Show Gist options
  • Save spetrunia/a09ad18f970d4ebe146e8cea5ed28bbd to your computer and use it in GitHub Desktop.
Save spetrunia/a09ad18f970d4ebe146e8cea5ed28bbd to your computer and use it in GitHub Desktop.
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 52fcbf96018..00dede9bc7d 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -5029,7 +5029,7 @@ subselect_hash_sj_engine::choose_partial_match_strategy(
strategy= PARTIAL_MATCH_SCAN;
else
item->get_IN_subquery()->get_materialization_tracker()->
- set_partial_match_buffer_size(pm_buff_size);
+ report_partial_match_buffer_size(pm_buff_size);
}
}
@@ -5805,7 +5805,7 @@ int subselect_hash_sj_engine::exec()
}
}
- item_in->get_materialization_tracker()->set_exec_strategy(strategy);
+ item_in->get_materialization_tracker()->report_exec_strategy(strategy);
if (pm_engine)
lookup_engine= pm_engine;
item_in->change_engine(lookup_engine);
@@ -6292,7 +6292,7 @@ int subselect_partial_match_engine::exec()
else
{
/* Search for a complete match. */
- tracker->increment_index_lookup_loops();
+ tracker->increment_index_lookups();
if ((lookup_res= lookup_engine->index_lookup()))
{
/* An error occurred during lookup(). */
@@ -6545,7 +6545,7 @@ subselect_rowid_merge_engine::init(MY_BITMAP *non_null_key_parts,
return TRUE;
item->get_IN_subquery()->get_materialization_tracker()->
- track_partial_merge_keys(merge_keys, merge_keys_count);
+ report_partial_merge_keys(merge_keys, merge_keys_count);
return FALSE;
}
@@ -7004,7 +7004,7 @@ void Item_subselect::init_expr_cache_tracker(THD *thd)
}
-void Subq_materialization_tracker::track_partial_merge_keys(
+void Subq_materialization_tracker::report_partial_merge_keys(
Ordered_key **merge_keys, uint merge_keys_count)
{
partial_match_array_sizes.resize(merge_keys_count, 0);
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 4a5c50fd71d..47aa0ffffcf 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -1580,108 +1580,71 @@ class Subq_materialization_tracker
partial_matches_count(0)
{}
- void track_partial_merge_keys(Ordered_key **merge_keys,
- uint merge_keys_count);
+ void report_partial_merge_keys(Ordered_key **merge_keys,
+ uint merge_keys_count);
- const char *get_exec_strategy() const
- {
- switch (exec_strategy)
- {
- case Strategy::UNDEFINED:
- return "undefined";
- case Strategy::COMPLETE_MATCH:
- return "index_lookup";
- case Strategy::PARTIAL_MATCH_MERGE:
- return "index_lookup;array merge for partial match";
- case Strategy::PARTIAL_MATCH_SCAN:
- return "index_lookup;full scan for partial match";
- default:
- return "unsupported";
- }
- }
-
- void set_exec_strategy(Strategy es)
+ void report_exec_strategy(Strategy es)
{
exec_strategy= es;
}
- bool has_partial_match_buffer_size() const
- {
- return partial_match_buffer_size != 0;
- }
-
- ulonglong get_partial_match_buffer_size() const
- {
- return partial_match_buffer_size;
- }
-
- void set_partial_match_buffer_size(longlong sz)
+ void report_partial_match_buffer_size(longlong sz)
{
partial_match_buffer_size= sz;
}
- size_t get_partial_match_arrays_count() const
- {
- return partial_match_array_sizes.elements();
- }
-
- ha_rows get_partial_match_array_size(size_t idx) const
- {
- return partial_match_array_sizes[idx];
- }
-
void increment_loops_count()
{
loops_count++;
}
- bool has_loops_count()
- {
- return loops_count != 0;
- }
-
- ulonglong get_loops_count() const
- {
- return loops_count;
- }
-
- void increment_index_lookup_loops()
+ void increment_index_lookups()
{
index_lookups_count++;
}
- bool has_index_lookup_loops()
- {
- return index_lookups_count != 0;
- }
-
- ulonglong get_index_lookup_loops_count() const
- {
- return index_lookups_count;
- }
-
void increment_partial_matches()
{
partial_matches_count++;
}
-
- bool has_partial_matches()
- {
- return partial_matches_count != 0;
- }
-
- ulonglong get_partial_matches_count() const
- {
- return partial_matches_count;
- }
-
+
+ void print_json_members(Json_writer *writer) const;
private:
Strategy exec_strategy;
ulonglong partial_match_buffer_size;
Dynamic_array<ha_rows> partial_match_array_sizes;
+
+ /* Number of times subquery predicate was evaluated */
ulonglong loops_count;
+
+ /*
+ Number of times we made a lookup in the materialized temptable
+ (we do this when all parts of left_expr are not NULLs)
+ */
ulonglong index_lookups_count;
+
+ /*
+ Number of times we had to check for a partial match (either by
+ scanning the materialized subquery or by doing a merge)
+ */
ulonglong partial_matches_count;
+
+ const char *get_exec_strategy() const
+ {
+ switch (exec_strategy)
+ {
+ case Strategy::UNDEFINED:
+ return "undefined";
+ case Strategy::COMPLETE_MATCH:
+ return "index_lookup";
+ case Strategy::PARTIAL_MATCH_MERGE:
+ return "index_lookup;array merge for partial match";
+ case Strategy::PARTIAL_MATCH_SCAN:
+ return "index_lookup;full scan for partial match";
+ default:
+ return "unsupported";
+ }
+ }
};
#endif /* ITEM_SUBSELECT_INCLUDED */
diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc
index 0b4ec367860..bfd73074f76 100644
--- a/sql/sql_explain.cc
+++ b/sql/sql_explain.cc
@@ -2717,33 +2717,34 @@ void Explain_subq_materialization::print_explain_json(Json_writer *writer,
{
writer->add_member("materialization").start_object();
if (is_analyze)
+ tracker.print_json_members(writer);
+}
+
+
+void Subq_materialization_tracker::print_json_members(Json_writer *writer) const
+{
+ writer->add_member("r_strategy").add_str(get_exec_strategy());
+ if (loops_count)
+ writer->add_member("r_loops").add_ull(loops_count);
+
+ if (index_lookups_count)
+ writer->add_member("r_index_lookups").add_ull(index_lookups_count);
+
+ if (partial_matches_count)
+ writer->add_member("r_partial_matches").add_ull(partial_matches_count);
+
+ if (partial_match_buffer_size)
{
- writer->add_member("r_strategy").add_str(tracker.get_exec_strategy());
- if (tracker.has_loops_count())
- {
- writer->add_member("r_loops").add_ull(tracker.get_loops_count());
- }
- if (tracker.has_index_lookup_loops())
- {
- writer->add_member("r_index_lookups").add_ull(
- tracker.get_index_lookup_loops_count());
- }
- if (tracker.has_partial_matches())
- {
- writer->add_member("r_partial_matches").add_ull(
- tracker.get_partial_matches_count());
- }
- if (tracker.has_partial_match_buffer_size())
- {
- writer->add_member("r_partial_match_buffer_size").add_size(
- tracker.get_partial_match_buffer_size());
- }
- if (tracker.get_partial_match_arrays_count() > 0)
- {
- writer->add_member("r_partial_match_array_sizes").start_array();
- for(size_t i= 0; i < tracker.get_partial_match_arrays_count(); i++)
- writer->add_ull(tracker.get_partial_match_array_size(i));
- writer->end_array();
- }
+ writer->add_member("r_partial_match_buffer_size").
+ add_size(partial_match_buffer_size);
+ }
+
+ if (partial_match_array_sizes.elements())
+ {
+ writer->add_member("r_partial_match_array_sizes").start_array();
+ for(size_t i= 0; i < partial_match_array_sizes.elements(); i++)
+ writer->add_ull(partial_match_array_sizes[i]);
+ writer->end_array();
}
}
+
diff --git a/sql/sql_explain.h b/sql/sql_explain.h
index 2c5cbcfb00e..845648eea57 100644
--- a/sql/sql_explain.h
+++ b/sql/sql_explain.h
@@ -117,8 +117,8 @@ class Explain_node : public Sql_alloc
Expression_cache_tracker* cache_tracker;
/**
- This member is not NULL if the node explains a materialized subquery.
- Otherwise it is NULL and not used
+ If not NULL, this node is a SELECT (or UNION) in a materialized
+ IN-subquery.
*/
Explain_subq_materialization* subq_materialization;
@@ -1013,7 +1013,10 @@ class Explain_delete: public Explain_update
/*
- EXPLAIN data structure for subquery materialization
+ EXPLAIN data structure for subquery materialization.
+
+ All decisions are made at execution time so here we just store the tracker
+ that has all the info.
*/
class Explain_subq_materialization : public Sql_alloc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment