double m_estimated_cost = -1.0; // Iterator执行完成预期的代价
double m_expected_rows = -1.0; // Iterator输出的行数
};
RowIterator::children
返回当前iterator的children list,包装结构为Child,部分Iterator在实现该方法时除了返回childrend iterator的指针以外,还返回了description。 例如:
mysql> explain format=tree select * from t1 join t2 on a1=b1 \G
*************************** 1. row ***************************
EXPLAIN: -> Inner hash join (t2.b1 = t1.a1) (cost=26269.36 rows=26214)
-> Table scan on t2 (cost=0.01 rows=512)
-> Hash
-> Table scan on t1 (cost=54.20 rows=512)
Iterator tree的结构如下:
HashJoinIterator
--> TableScanIterator // t2, probe side
--> TableScanIterator // t1, build side
HashJoinIterator的children方法返回的内容如下:
{<TableScanIterator(t2), null>,
<TableScanIterator(t1), "Hash">}
其中Hash是description, 这里表示对t1表build hash然后再去join t2表。
RowIterator::DebugString()
产生Iterator的格式化字符串, 每个Iterator都有自己的实现,主要是描述Iterator的行为,包括Table Scan的方式, 过滤的Condition,Join method等等, 通常都是一
行。
Explain Format Tree 介绍
执行过程
Explain
- handle_query()
- SELECT_LEX_UNIT::optimize()
- SELECT_LEX::optimize()
- JOIN::optimize()
- JOIN::create_iterators() // 创建join的iterators
- JOIN::create_table_iterators()
- JOIN::create_root_iterator_for_join()
- JOIN::attach_iterators_for_having_and_limit()
- SELECT_LEX_UNIT::create_iterators() // 创建union的iterators
- explain_query()
- ExplainIterator() // 如果explain_format = tree,调用此接口输出执行计划
- PrintQueryPlan() // 将iterator的信息格式化为tree格式的执行计划字符串,该接口会对iteratortree进行递归
- FullDebugString() // 生成iterator的计划信息
PrintQueryPlan()
std::string PrintQueryPlan(int level, RowIterator *iterator) {
string ret;
if (iterator == nullptr) {
ret.assign(level * 4, ' ');
return ret + "<not executable by iterator executor>\n";
}
int top_level = level; // 当前缩进level, 每个level缩进4个空格
// 输出自身的计划信息
for (const string &str : FullDebugString(current_thd, *iterator)) {
ret.append(level * 4, ' ');
ret += "-> ";
评论