18 #include "opt_explain.h"
20 #include "sql_optimizer.h"
21 #include "sql_partition.h"
22 #include "sql_join_buffer.h"
24 #include "opt_explain_format.h"
29 static bool mysql_explain_unit(THD *thd, SELECT_LEX_UNIT *unit,
30 select_result *result);
31 static void propagate_explain_option(THD *thd, SELECT_LEX_UNIT *unit);
33 const char *join_type_str[]={
"UNKNOWN",
"system",
"const",
"eq_ref",
"ref",
34 "ALL",
"range",
"index",
"fulltext",
35 "ref_or_null",
"unique_subquery",
"index_subquery",
39 static const enum_query_type cond_print_flags=
40 enum_query_type(QT_ORDINARY | QT_SHOW_SELECT_NUMBER);
69 Item *
const condition;
76 condition->
print(ret, cond_print_flags);
81 explicit Explain(Explain_context_enum context_type_arg,
82 THD *thd_arg,
JOIN *join_arg= NULL)
84 cs(system_charset_info),
87 fmt(
thd->lex->explain_format),
95 group_list=
join->group_list;
99 if (select_lex()->order_list.elements)
102 if (select_lex()->group_list.elements)
123 Explain_context_enum
type);
126 bool describe(uint8 mask)
const {
return thd->lex->describe & mask; }
128 SELECT_LEX *select_lex()
const
147 DBUG_ASSERT(
join == NULL);
149 return result->prepare(dummy, select_lex()->master_unit()) ||
213 virtual bool explain_id();
214 virtual bool explain_select_type();
215 virtual bool explain_table_name() {
return false; }
216 virtual bool explain_partitions() {
return false; }
217 virtual bool explain_join_type() {
return false; }
218 virtual bool explain_possible_keys() {
return false; }
221 virtual bool explain_ref() {
return false; }
224 virtual bool explain_extra() {
return false; }
225 virtual bool explain_modify_flags() {
return false; }
248 :
Explain(CTX_JOIN, thd_arg, join_arg),
249 message(message_arg), rows(HA_POS_ERROR)
253 ha_rows rows_arg= HA_POS_ERROR)
255 message(message_arg), rows(rows_arg)
262 virtual bool explain_extra();
274 :
Explain(CTX_UNION_RESULT, thd_arg, join_arg)
277 DBUG_ASSERT(join_arg->
select_lex == join_arg->
unit->fake_select_lex);
281 virtual bool explain_id();
282 virtual bool explain_table_name();
283 virtual bool explain_join_type();
284 virtual bool explain_extra();
299 THD *
const thd_arg,
JOIN *
const join_arg)
300 :
Explain(context_type_arg, thd_arg, join_arg), table(NULL)
304 THD *
const thd_arg,
TABLE *
const table_arg)
305 :
Explain(context_type_arg, thd_arg), table(table_arg)
308 virtual bool explain_partitions();
309 virtual bool explain_possible_keys();
311 bool explain_key_parts(
int key, uint key_parts);
312 bool explain_key_and_len_quick(
const SQL_SELECT *select);
313 bool explain_key_and_len_index(
int key);
314 bool explain_key_and_len_index(
int key, uint key_length, uint key_parts);
315 bool explain_extra_common(
const SQL_SELECT *select,
319 bool explain_tmptable_and_filesort(
bool need_tmp_table_arg,
321 virtual bool explain_modify_flags();
340 table_map used_tables;
344 bool need_tmp_table_arg,
bool need_order_arg,
347 need_tmp_table(need_tmp_table_arg),
348 need_order(need_order_arg), distinct(distinct_arg),
349 tabnum(0), select(0), used_tables(0)
352 DBUG_ASSERT(join_arg->
select_lex != join_arg->
unit->fake_select_lex);
357 bool begin_sort_context(Explain_sort_clause clause, Explain_context_enum ctx);
358 bool end_sort_context(Explain_sort_clause clause, Explain_context_enum ctx);
359 bool begin_simple_sort_context(Explain_sort_clause clause,
360 Explain_context_enum ctx);
361 bool end_simple_sort_context(Explain_sort_clause clause,
362 Explain_context_enum ctx);
363 bool explain_join_tab(
size_t tab_num);
368 virtual bool explain_table_name();
369 virtual bool explain_join_type();
371 virtual bool explain_ref();
373 virtual bool explain_extra();
374 virtual bool explain_select_type();
375 virtual bool explain_id();
393 const bool need_tmp_table;
394 const bool need_sort;
395 const bool is_update;
396 const bool used_key_is_modified;
401 uint key_arg, ha_rows limit_arg,
402 bool need_tmp_table_arg,
bool need_sort_arg,
403 bool is_update_arg,
bool used_key_is_modified_arg)
405 select(select_arg), key(key_arg),
407 need_tmp_table(need_tmp_table_arg), need_sort(need_sort_arg),
408 is_update(is_update_arg), used_key_is_modified(used_key_is_modified_arg)
410 usable_keys= table->possible_quick_keys;
413 virtual bool explain_modify_flags();
416 virtual bool explain_tmptable_and_filesort(
bool need_tmp_table_arg,
418 virtual bool shallow_explain();
420 virtual bool explain_ref();
421 virtual bool explain_table_name();
422 virtual bool explain_join_type();
423 virtual bool explain_key_and_len();
424 virtual bool explain_rows_and_filtered();
425 virtual bool explain_extra();
429 static join_type calc_join_type(
int quick_type)
431 if ((quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE) ||
432 (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) ||
433 (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION))
434 return JT_INDEX_MERGE;
465 Explain_context_enum
type)
473 item->compile(&Item::explain_subquery_checker,
474 reinterpret_cast<uchar **>(&marker_ptr),
475 &Item::explain_subquery_propagator,
486 Explain_context_enum sq_context;
489 sq_context= CTX_ORDER_BY_SQ;
492 sq_context= CTX_GROUP_BY_SQ;
502 for (
const ORDER *o= order; o; o= o->next)
516 for (uint part_no= 0; part_no < key_parts; part_no++)
518 const store_key *
const s_key= key_copy[part_no];
546 if (mark_order_subqueries(group_list))
560 if (&
thd->lex->select_lex == select_lex() &&
561 !
thd->lex->value_list.is_empty())
567 DBUG_ASSERT(
thd->lex->sql_command == SQLCOM_UPDATE ||
568 thd->lex->sql_command == SQLCOM_UPDATE_MULTI ||
569 thd->lex->sql_command == SQLCOM_INSERT ||
570 thd->lex->sql_command == SQLCOM_INSERT_SELECT);
580 if (mark_order_subqueries(order_list))
583 for (SELECT_LEX_UNIT *unit= select_lex()->first_inner_unit();
585 unit= unit->next_unit())
587 SELECT_LEX *sl= unit->first_select();
588 Explain_context_enum context;
589 if (sl->type(
thd) == SELECT_LEX::SLT_DERIVED)
591 DBUG_ASSERT(unit->explain_marker == CTX_NONE);
592 context= CTX_DERIVED;
594 else if (unit->explain_marker == CTX_NONE)
595 context= CTX_OPTIMIZED_AWAY_SUBQUERY;
597 context=
static_cast<Explain_context_enum
>(unit->explain_marker);
602 if (mysql_explain_unit(
thd, unit, result))
610 (context == CTX_WHERE || context == CTX_HAVING ||
611 context == CTX_SELECT_LIST ||
612 context == CTX_GROUP_BY_SQ || context == CTX_ORDER_BY_SQ) &&
614 (unit->item->get_engine_for_explain()->engine_type() ==
615 subselect_engine::HASH_SJ_ENGINE))
617 fmt->
entry()->is_materialized_from_subquery=
true;
619 fmt->
entry()->using_temporary=
true;
625 (unit->item->get_engine_for_explain());
626 const JOIN_TAB *
const tmp_tab= engine->get_join_tab();
628 char buff_key_len[24];
630 longlong2str(tmp_tab->table->key_info[0].
key_length,
631 buff_key_len, 10) - buff_key_len);
633 if (explain_ref_key(fmt, tmp_tab->ref.
key_parts,
642 fmt->
entry()->is_dependent=
true;
643 fmt->
entry()->is_cacheable=
false;
658 return explain_id() ||
659 explain_select_type() ||
660 explain_table_name() ||
661 explain_partitions() ||
662 explain_join_type() ||
663 explain_possible_keys() ||
668 explain_modify_flags();
684 DBUG_ENTER(
"Explain::send");
690 thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
691 SERVER_QUERY_NO_GOOD_INDEX_USED);
693 select_result *result;
697 if (!(result=
new select_send))
708 for (SELECT_LEX_UNIT *unit= select_lex()->first_inner_unit();
710 unit= unit->next_unit())
711 propagate_explain_option(
thd, unit);
724 result->abort_result_set();
734 bool Explain::explain_id()
736 fmt->
entry()->
col_id.set(select_lex()->select_number);
741 bool Explain::explain_select_type()
743 if (&
thd->lex->select_lex != select_lex())
745 fmt->
entry()->is_dependent= select_lex()->is_dependent();
746 if (select_lex()->
type(
thd) != SELECT_LEX::SLT_DERIVED)
747 fmt->
entry()->is_cacheable= select_lex()->is_cacheable();
768 if (rows == HA_POS_ERROR)
775 bool Explain_no_table::explain_extra()
784 bool Explain_union_result::explain_id()
790 bool Explain_union_result::explain_table_name()
792 SELECT_LEX *last_select=
join->
unit->first_select()->last_select();
794 int last_length= (int)log10((
double)last_select->select_number)+1;
796 SELECT_LEX *sl=
join->
unit->first_select();
797 uint len= 6, lastop= 0;
798 char table_name_buffer[NAME_LEN];
799 memcpy(table_name_buffer, STRING_WITH_LEN(
"<union"));
806 sl && len + lastop + 6 + last_length < NAME_CHAR_LEN;
807 sl= sl->next_select())
810 lastop= my_snprintf(table_name_buffer + len, NAME_CHAR_LEN - len,
811 "%u,", sl->select_number);
813 if (sl || len + lastop >= NAME_CHAR_LEN)
815 memcpy(table_name_buffer + len, STRING_WITH_LEN(
"...,"));
817 lastop= my_snprintf(table_name_buffer + len, NAME_CHAR_LEN - len,
818 "%u,", last_select->select_number);
821 table_name_buffer[len - 1]=
'>';
827 bool Explain_union_result::explain_join_type()
834 bool Explain_union_result::explain_extra()
850 if (
join->
unit->global_parameters->order_list.first)
855 return Explain::explain_extra();
862 bool Explain_table_base::explain_partitions()
864 #ifdef WITH_PARTITION_STORAGE_ENGINE
865 if (!table->pos_in_table_list->
derived && table->part_info)
866 return make_used_partitions_str(table->part_info,
873 bool Explain_table_base::explain_possible_keys()
875 if (usable_keys.is_clear_all())
878 for (uint j= 0 ; j < table->s->keys ; j++)
880 if (usable_keys.is_set(j) &&
888 bool Explain_table_base::explain_key_parts(
int key, uint key_parts)
891 for (uint
i= 0;
i < key_parts;
i++, kp++)
898 bool Explain_table_base::explain_key_and_len_quick(
const SQL_SELECT *select)
900 DBUG_ASSERT(select && select->quick);
906 if (select->quick->index != MAX_KEY)
907 ret= explain_key_parts(select->quick->index,
908 select->quick->used_key_parts);
909 select->quick->add_keys_and_lengths(&str_key, &str_key_len);
915 bool Explain_table_base::explain_key_and_len_index(
int key)
917 DBUG_ASSERT(key != MAX_KEY);
918 return explain_key_and_len_index(key, table->key_info[key].
key_length,
923 bool Explain_table_base::explain_key_and_len_index(
int key, uint key_length,
926 DBUG_ASSERT(key != MAX_KEY);
928 char buff_key_len[24];
929 const KEY *key_info= table->key_info + key;
930 const int length= longlong2str(key_length, buff_key_len, 10) - buff_key_len;
931 const bool ret= explain_key_parts(key, key_parts);
937 bool Explain_table_base::explain_extra_common(
const SQL_SELECT *select,
942 if (((keyno != MAX_KEY &&
943 keyno == table->file->pushed_idx_cond_keyno &&
944 table->file->pushed_idx_cond) ||
945 (tab && tab->cache_idx_cond)))
950 if (table->file->pushed_idx_cond)
951 table->file->pushed_idx_cond->
print(&buff, cond_print_flags);
953 tab->cache_idx_cond->
print(&buff, cond_print_flags);
955 if (
push_extra(ET_USING_INDEX_CONDITION, buff))
966 for (
JOIN_TAB* prev=
join->join_tab; prev <= tab; prev++)
969 if (prev_root == prev->table)
972 if (prev_root == pushed_root)
976 if (pushed_root == table)
979 len= my_snprintf(buf,
sizeof(buf)-1,
980 "Parent of %d pushed join@%d",
981 pushed_count, pushed_id);
985 len= my_snprintf(buf,
sizeof(buf)-1,
986 "Child of '%s' in pushed join@%d",
993 buff.append(buf,len);
999 switch (quick_type) {
1000 case QUICK_SELECT_I::QS_TYPE_ROR_UNION:
1001 case QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT:
1002 case QUICK_SELECT_I::QS_TYPE_INDEX_MERGE:
1005 select->quick->add_info_string(&buff);
1028 if (tab && tab->use_quick == QS_DYNAMIC_RANGE)
1032 char buf[MAX_KEY / 4 + 1];
1033 str.append(tab->
keys.print(buf));
1034 if (
push_extra(ET_RANGE_CHECKED_FOR_EACH_RECORD, str))
1037 else if (select->cond)
1039 const Item *pushed_cond= table->file->pushed_cond;
1041 if (
thd->optimizer_switch_flag(OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN) &&
1045 if (describe(DESCRIBE_EXTENDED))
1046 ((
Item *)pushed_cond)->print(&buff, cond_print_flags);
1047 if (
push_extra(ET_USING_WHERE_WITH_PUSHED_CONDITION, buff))
1054 Lazy_condition *c=
new Lazy_condition(tab && !tab->filesort ?
1066 DBUG_ASSERT(!tab || !tab->condition());
1068 if (table->reginfo.not_exists_optimize &&
push_extra(ET_NOT_EXISTS))
1071 if (quick_type == QUICK_SELECT_I::QS_TYPE_RANGE)
1085 if (mrr_flags & HA_MRR_SORTED && !(mrr_flags & HA_MRR_SUPPORT_SORTED))
1086 mrr_flags|= HA_MRR_USE_DEFAULT_IMPL;
1088 if (!(mrr_flags & HA_MRR_USE_DEFAULT_IMPL) &&
push_extra(ET_USING_MRR))
1094 bool Explain_table_base::explain_tmptable_and_filesort(
bool need_tmp_table_arg,
1104 if (need_tmp_table_arg &&
push_extra(ET_USING_TEMPORARY))
1106 if (need_sort_arg &&
push_extra(ET_USING_FILESORT))
1112 bool Explain_table_base::explain_modify_flags()
1116 switch (
thd->lex->sql_command) {
1117 case SQLCOM_UPDATE_MULTI:
1118 if (!bitmap_is_clear_all(table->write_set) &&
1120 fmt->
entry()->is_update=
true;
1122 case SQLCOM_DELETE_MULTI:
1124 TABLE_LIST *aux_tables=
thd->lex->auxiliary_table_list.first;
1125 for (
TABLE_LIST *at= aux_tables; at; at= at->next_local)
1127 if (at->table == table)
1129 fmt->
entry()->is_delete=
true;
1143 bool Explain_join::begin_sort_context(Explain_sort_clause clause,
1144 Explain_context_enum ctx)
1147 return (flags->
get(clause, ESP_EXISTS) &&
1148 !flags->
get(clause, ESP_IS_SIMPLE) &&
1153 bool Explain_join::end_sort_context(Explain_sort_clause clause,
1154 Explain_context_enum ctx)
1157 return (flags->
get(clause, ESP_EXISTS) &&
1158 !flags->
get(clause, ESP_IS_SIMPLE) &&
1163 bool Explain_join::begin_simple_sort_context(Explain_sort_clause clause,
1164 Explain_context_enum ctx)
1167 return (flags->
get(clause, ESP_IS_SIMPLE) &&
1172 bool Explain_join::end_simple_sort_context(Explain_sort_clause clause,
1173 Explain_context_enum ctx)
1176 return (flags->
get(clause, ESP_IS_SIMPLE) &&
1183 if (begin_sort_context(ESC_ORDER_BY, CTX_ORDER_BY))
1185 if (begin_sort_context(ESC_DISTINCT, CTX_DISTINCT))
1187 if (begin_sort_context(ESC_GROUP_BY, CTX_GROUP_BY))
1189 if (begin_sort_context(ESC_BUFFER_RESULT, CTX_BUFFER_RESULT))
1196 if (explain_join_tab(t))
1200 if (end_sort_context(ESC_BUFFER_RESULT, CTX_BUFFER_RESULT))
1202 if (end_sort_context(ESC_GROUP_BY, CTX_GROUP_BY))
1204 if (end_sort_context(ESC_DISTINCT, CTX_DISTINCT))
1206 if (end_sort_context(ESC_ORDER_BY, CTX_ORDER_BY))
1213 bool Explain_join::explain_join_tab(
size_t tab_num)
1216 tab=
join->join_tab + tabnum;
1220 usable_keys= tab->
keys;
1222 select= (tab->filesort && tab->filesort->
select) ?
1223 tab->filesort->
select : tab->select;
1225 if (tab->type == JT_ALL && select && select->quick)
1227 quick_type= select->quick->get_type();
1228 tab->type= calc_join_type(quick_type);
1236 if (first_non_const)
1238 if (begin_simple_sort_context(ESC_ORDER_BY, CTX_SIMPLE_ORDER_BY))
1240 if (begin_simple_sort_context(ESC_DISTINCT, CTX_SIMPLE_DISTINCT))
1242 if (begin_simple_sort_context(ESC_GROUP_BY, CTX_SIMPLE_GROUP_BY))
1247 Explain_context_enum c= sjm ? CTX_MATERIALIZATION : CTX_JOIN_TAB;
1275 if (explain_join_tab(sjt))
1283 if (first_non_const)
1285 if (end_simple_sort_context(ESC_GROUP_BY, CTX_SIMPLE_GROUP_BY))
1287 if (end_simple_sort_context(ESC_DISTINCT, CTX_SIMPLE_DISTINCT))
1289 if (end_simple_sort_context(ESC_ORDER_BY, CTX_SIMPLE_ORDER_BY))
1293 if (tab->check_weed_out_table &&
1297 used_tables|= table->map;
1303 bool Explain_join::explain_table_name()
1308 char table_name_buffer[NAME_LEN];
1309 const size_t len= my_snprintf(table_name_buffer,
1310 sizeof(table_name_buffer) - 1,
1320 bool Explain_join::explain_select_type()
1325 return Explain::explain_select_type();
1330 bool Explain_join::explain_id()
1335 return Explain::explain_id();
1340 bool Explain_join::explain_join_type()
1350 return explain_key_and_len_index(tab->ref.
key, tab->ref.
key_length,
1352 else if (tab->type == JT_INDEX_SCAN)
1353 return explain_key_and_len_index(tab->
index);
1354 else if (select && select->quick)
1355 return explain_key_and_len_quick(select);
1358 const TABLE_LIST *table_list= table->pos_in_table_list;
1359 if (table_list->schema_table &&
1360 table_list->schema_table->i_s_requested_object & OPTIMIZE_I_S_TABLE)
1365 if (table_list->has_db_lookup_value)
1367 f_idx= table_list->schema_table->idx_field1;
1368 f_name= table_list->schema_table->fields_info[f_idx].
field_name;
1369 str_key.append(f_name, strlen(f_name),
cs);
1371 if (table_list->has_table_lookup_value)
1373 if (table_list->has_db_lookup_value)
1374 str_key.append(
',');
1375 f_idx= table_list->schema_table->idx_field2;
1376 f_name= table_list->schema_table->fields_info[f_idx].
field_name;
1377 str_key.append(f_name, strlen(f_name),
cs);
1379 if (str_key.length())
1387 bool Explain_join::explain_ref()
1395 if (table->pos_in_table_list->schema_table)
1398 double examined_rows;
1399 if (select && select->quick)
1400 examined_rows= rows2double(select->quick->records);
1401 else if (tab->type == JT_INDEX_SCAN || tab->type == JT_ALL)
1404 examined_rows= rows2double(tab->limit);
1408 examined_rows= rows2double(table->file->stats.records);
1412 examined_rows= tab->
position->records_read;
1414 fmt->
entry()->
col_rows.set(static_cast<longlong>(examined_rows));
1417 if (describe(DESCRIBE_EXTENDED))
1421 f= 100.0 * tab->
position->records_read / examined_rows;
1428 bool Explain_join::explain_extra()
1435 else if (tab->packed_info & TAB_INFO_HAVE_VALUE)
1437 if (tab->packed_info & TAB_INFO_USING_INDEX)
1442 if (tab->packed_info & TAB_INFO_USING_WHERE)
1446 Lazy_condition *c=
new Lazy_condition(tab->condition());
1454 if (tab->packed_info & TAB_INFO_FULL_SCAN_ON_NULL)
1457 extra(ET_FULL_SCAN_ON_NULL_KEY)))
1463 uint keyno= MAX_KEY;
1465 keyno= tab->ref.
key;
1466 else if (select && select->quick)
1467 keyno = select->quick->index;
1469 if (explain_extra_common(select, tab, quick_type, keyno))
1472 const TABLE_LIST *table_list= table->pos_in_table_list;
1473 if (table_list->schema_table &&
1474 table_list->schema_table->i_s_requested_object & OPTIMIZE_I_S_TABLE)
1476 if (!table_list->table_open_method)
1481 else if (table_list->table_open_method == OPEN_FRM_ONLY)
1493 if (table_list->has_db_lookup_value &&
1494 table_list->has_table_lookup_value)
1499 else if (table_list->has_db_lookup_value ||
1500 table_list->has_table_lookup_value)
1511 if (((tab->type == JT_INDEX_SCAN || tab->type == JT_CONST) &&
1512 table->covering_keys.is_set(tab->
index)) ||
1513 (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT &&
1517 if (quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)
1522 qgs->append_loose_scan_type(&buff);
1523 if (
push_extra(ET_USING_INDEX_FOR_GROUP_BY, buff))
1533 if (explain_tmptable_and_filesort(need_tmp_table, need_order))
1535 need_tmp_table= need_order=
false;
1537 if (distinct && test_all_bits(used_tables,
thd->lex->used_tables) &&
1556 if (tab->firstmatch_return ==
join->join_tab - 1)
1564 TABLE *prev_table= tab->firstmatch_return->table;
1567 prev_table->pos_in_table_list->
derived)
1569 char namebuf[NAME_LEN];
1571 int len= my_snprintf(namebuf,
sizeof(namebuf)-1,
1574 buff.append(namebuf, len);
1577 buff.append(prev_table->pos_in_table_list->alias);
1590 buff.append(
"Block Nested Loop");
1592 buff.append(
"Batched Key Access");
1594 buff.append(
"Batched Key Access (unique)");
1607 bool Explain_table::explain_modify_flags()
1612 fmt->
entry()->is_update=
true;
1614 fmt->
entry()->is_delete=
true;
1619 bool Explain_table::explain_tmptable_and_filesort(
bool need_tmp_table_arg,
1631 if (need_tmp_table_arg)
1633 DBUG_ASSERT(used_key_is_modified || order_list);
1634 if (used_key_is_modified &&
push_extra(ET_USING_TEMPORARY,
"for update"))
1640 if (need_tmp_table_arg &&
push_extra(ET_USING_TEMPORARY))
1643 if (need_sort_arg &&
push_extra(ET_USING_FILESORT))
1651 bool Explain_table::shallow_explain()
1656 flags.
set(ESC_ORDER_BY, ESP_EXISTS);
1658 flags.
set(ESC_ORDER_BY, ESP_USING_FILESORT);
1659 if (!used_key_is_modified && need_tmp_table)
1660 flags.
set(ESC_ORDER_BY, ESP_USING_TMPTABLE);
1663 if (order_list && fmt->
begin_context(CTX_ORDER_BY, NULL, &flags))
1683 bool Explain_table::explain_table_name()
1689 bool Explain_table::explain_join_type()
1692 if (select && select->quick)
1693 jt= calc_join_type(select->quick->get_type());
1694 else if (key != MAX_KEY)
1704 bool Explain_table::explain_ref()
1706 if (select && select->quick)
1708 int key_parts= select->quick->used_key_parts;
1718 bool Explain_table::explain_key_and_len()
1720 if (select && select->quick)
1721 return explain_key_and_len_quick(select);
1722 else if (key != MAX_KEY)
1723 return explain_key_and_len_index(key);
1728 bool Explain_table::explain_rows_and_filtered()
1730 double examined_rows;
1731 if (select && select->quick)
1732 examined_rows= rows2double(select->quick->records);
1733 else if (!select && !need_sort && limit != HA_POS_ERROR)
1734 examined_rows= rows2double(limit);
1738 examined_rows= rows2double(table->file->stats.records);
1741 fmt->
entry()->
col_rows.set(static_cast<long long>(examined_rows));
1743 if (describe(DESCRIBE_EXTENDED))
1750 bool Explain_table::explain_extra()
1752 const uint keyno= (select && select->quick) ? select->quick->index : key;
1753 const int quick_type= (select && select->quick) ? select->quick->get_type()
1755 return (explain_extra_common(select, NULL, quick_type, keyno) ||
1756 explain_tmptable_and_filesort(need_tmp_table, need_sort));
1800 explain_send(select_result_interceptor *interceptor_arg)
1806 virtual int prepare(
List<Item> &list, SELECT_LEX_UNIT *u)
1811 return select_send::prepare(list, u) ||
interceptor->prepare(list, u);
1814 virtual int prepare2(
void)
1819 return select_send::prepare2() ||
interceptor->prepare2();
1822 virtual bool initialize_tables(
JOIN *join)
1827 return select_send::initialize_tables(join) ||
1831 virtual void cleanup()
1833 select_send::cleanup();
1860 bool explain_no_table(THD *thd,
JOIN *join,
const char *
message)
1862 DBUG_ENTER(
"explain_no_table");
1883 bool explain_no_table(THD *thd,
const char *message, ha_rows rows)
1885 DBUG_ENTER(
"explain_no_table");
1918 bool explain_single_table_modification(THD *thd,
1923 bool need_tmp_table,
1926 bool used_key_is_modified)
1928 DBUG_ENTER(
"explain_single_table_modification");
1929 const bool ret=
Explain_table(thd, table, select, key, limit,
1930 need_tmp_table, need_sort, is_update,
1931 used_key_is_modified).
send();
1953 bool explain_query_specification(THD *thd,
JOIN *join)
1956 const bool need_tmp_table= flags->
any(ESP_USING_TMPTABLE);
1957 const bool need_order= flags->
any(ESP_USING_FILESORT);
1958 const bool distinct= flags->
get(ESC_DISTINCT, ESP_EXISTS);
1960 DBUG_ENTER(
"explain_query_specification");
1961 DBUG_PRINT(
"info", (
"Select %p, type %s",
1996 bool explain_multi_table_modification(THD *thd,
1997 select_result_interceptor *result)
1999 DBUG_ENTER(
"explain_multi_table_modification");
2001 bool res= explain_query_expression(thd, &explain);
2030 bool explain_query_expression(THD *thd, select_result *result)
2032 DBUG_ENTER(
"explain_query_expression");
2033 const bool res= thd->lex->explain_format->send_headers(result) ||
2034 mysql_explain_unit(thd, &thd->lex->unit, result) ||
2040 if (!res && (thd->lex->describe & DESCRIBE_EXTENDED) &&
2041 thd->lex->sql_command == SQLCOM_SELECT)
2047 thd->lex->unit.print(&str, enum_query_type(QT_TO_SYSTEM_CHARSET |
2048 QT_SHOW_SELECT_NUMBER));
2050 push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, ER_YES, str.ptr());
2053 result->abort_result_set();
2066 static void propagate_explain_option(THD *thd, SELECT_LEX_UNIT *unit)
2068 for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
2069 sl->options|= SELECT_DESCRIBE;
2085 bool mysql_explain_unit(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
2087 DBUG_ENTER(
"mysql_explain_unit");
2090 propagate_explain_option(thd, unit);
2092 if (unit->is_union())
2094 unit->fake_select_lex->select_number= UINT_MAX;
2095 unit->fake_select_lex->options|= SELECT_DESCRIBE;
2097 res= unit->prepare(thd, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE);
2110 if (! thd->lex->is_query_tables_locked() &&
2111 lock_tables(thd, thd->lex->query_tables, thd->lex->table_count, 0))
2114 res= unit->optimize();
2117 res= unit->explain();
2121 SELECT_LEX *first= unit->first_select();
2122 thd->lex->current_select= first;
2123 unit->set_limit(unit->global_parameters);
2125 first->table_list.first,
2126 first->with_wild, first->item_list,
2131 first->options | thd->variables.option_bits | SELECT_DESCRIBE,
2132 result, unit, first);
2134 DBUG_RETURN(res || thd->is_error());