diff options
author | Oleksandr Byelkin <sanja@mariadb.com> | 2015-04-02 18:19:33 +0200 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2015-04-03 15:37:27 +0200 |
commit | a220905083c382bec096dd1435b6620d348bbfeb (patch) | |
tree | 15cb6f7d3d7bd05d47568662cb74641d073675f6 /sql/sql_explain.cc | |
parent | 7f613ebdb6865e2d1304d20977764b523f6a5080 (diff) | |
download | mariadb-git-a220905083c382bec096dd1435b6620d348bbfeb.tar.gz |
MDEV-7833:ANALYZE FORMAT=JSON and Range checked for each record
Diffstat (limited to 'sql/sql_explain.cc')
-rw-r--r-- | sql/sql_explain.cc | 106 |
1 files changed, 101 insertions, 5 deletions
diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc index 6c353185cb1..c1f1b0218b5 100644 --- a/sql/sql_explain.cc +++ b/sql/sql_explain.cc @@ -22,6 +22,7 @@ #include "sql_priv.h" #include "sql_select.h" #include "my_json_writer.h" +#include "opt_range.h" const char * STR_DELETING_ALL_ROWS= "Deleting all rows"; const char * STR_IMPOSSIBLE_WHERE= "Impossible WHERE"; @@ -1076,15 +1077,26 @@ int Explain_table_access::print_explain(select_result_sink *output, uint8 explai } -bool String_list::append_str(MEM_ROOT *mem_root, const char *str) +/** + Adds copy of the string to the list + + @param mem_root where to allocate string + @param str string to copy and add + + @return + NULL - out of memory error + poiner on allocated copy of the string +*/ + +const char *String_list::append_str(MEM_ROOT *mem_root, const char *str) { size_t len= strlen(str); char *cp; if (!(cp = (char*)alloc_root(mem_root, len+1))) - return 1; + return NULL; memcpy(cp, str, len+1); push_back(cp); - return 0; + return cp; } @@ -1207,8 +1219,7 @@ void Explain_table_access::print_explain_json(Explain_query *query, if (range_checked_fer) { - writer->add_member("range-checked-for-each-record").start_object(); - add_json_keyset(writer, "keys", &possible_keys); + range_checked_fer->print_json(writer, is_analyze); } if (full_scan_on_null_key) @@ -1986,3 +1997,88 @@ void create_explain_query_if_not_exists(LEX *lex, MEM_ROOT *mem_root) create_explain_query(lex, mem_root); } + +/** + Build arrays for collectiong keys statistics, sdd possible key names + to the list and name array + + @param alloc MEM_ROOT to put data in + @param list list of possible key names to fill + @param table table of the keys + @patam possible_keys possible keys map + + @retval 0 - OK + @retval 1 - Error +*/ + +int Explain_range_checked_fer::append_possible_keys_stat(MEM_ROOT *alloc, + TABLE *table, + key_map possible_keys) +{ + uint j; + multi_alloc_root(alloc, &keys_stat, sizeof(ha_rows) * table->s->keys, + &keys_stat_names, sizeof(char *) * table->s->keys, NULL); + if ((!keys_stat) || (!keys_stat_names)) + { + keys_stat= NULL; + keys_stat_names= NULL; + return 1; + } + keys_map= possible_keys; + keys= table->s->keys; + bzero(keys_stat, sizeof(ha_rows) * table->s->keys); + for (j= 0; j < table->s->keys; j++) + { + if (possible_keys.is_set(j)) + keys_stat_names[j]= key_set.append_str(alloc, table->key_info[j].name); + else + keys_stat_names[j]= NULL; + } + return 0; +} + +void Explain_range_checked_fer::collect_data(QUICK_SELECT_I *quick) +{ + if (quick) + { + if (quick->index == MAX_KEY) + index_merge++; + else + { + DBUG_ASSERT(quick->index < keys); + DBUG_ASSERT(keys_stat); + DBUG_ASSERT(keys_stat_names); + DBUG_ASSERT(keys_stat_names[ quick->index]); + keys_stat[quick->index]++; + } + } + else + full_scan++; +} + + +void Explain_range_checked_fer::print_json(Json_writer *writer, + bool is_analyze) +{ + writer->add_member("range-checked-for-each-record").start_object(); + add_json_keyset(writer, "keys", &key_set); + if (is_analyze) + { + writer->add_member("r_keys").start_object(); + writer->add_member("full_scan").add_ll(full_scan); + writer->add_member("index_merge").add_ll(index_merge); + if (keys_stat) + { + writer->add_member("range").start_object(); + for (uint i= 0; i < keys; i++) + { + if (keys_stat_names[i]) + { + writer->add_member(keys_stat_names[i]).add_ll(keys_stat[i]); + } + } + writer->end_object(); + } + writer->end_object(); + } +} |