20 #include "sql_optimizer.h"
21 #include "abstract_query_plan.h"
22 #include "sql_join_buffer.h"
32 : m_join_tabs(join->join_tab),
33 m_access_count(join->primary_tables),
34 m_table_accesses(NULL)
40 DBUG_ASSERT((m_join_tabs[0].use_quick != 2)
41 || (m_join_tabs[0].
type == JT_ALL)
42 || (m_join_tabs[0].select == NULL)
43 || (m_join_tabs[0].select->quick == NULL));
46 for(uint
i= 0;
i < m_access_count;
i++)
48 m_table_accesses[
i].m_join_plan=
this;
49 m_table_accesses[
i].m_tab_no=
i;
53 Join_plan::~Join_plan()
55 delete[] m_table_accesses;
56 m_table_accesses= NULL;
60 const JOIN_TAB* Join_plan::get_join_tab(uint join_tab_no)
const
62 DBUG_ASSERT(join_tab_no < m_access_count);
63 return m_join_tabs + join_tab_no;
73 DBUG_ENTER(
"get_join_type");
77 if (first_inner == NULL)
80 DBUG_PRINT(
"info", (
"JT_INNER_JOIN'ed table %s",
81 get_join_tab()->
table->alias));
82 DBUG_RETURN(JT_INNER_JOIN);
91 if (predecessor->get_join_tab() >= first_inner &&
92 predecessor->get_join_tab() <= last_inner)
94 DBUG_PRINT(
"info", (
"JT_INNER_JOIN between %s and %s",
95 predecessor->get_join_tab()->table->alias,
96 get_join_tab()->table->alias));
97 DBUG_RETURN(JT_INNER_JOIN);
101 DBUG_PRINT(
"info", (
"JT_OUTER_JOIN between %s and %s",
102 predecessor->get_join_tab()->table->alias,
103 get_join_tab()->table->alias));
104 DBUG_RETURN(JT_OUTER_JOIN);
131 return get_join_tab()->ref.
items[field_no];
142 const KEY* key= &get_join_tab()->table->key_info[get_join_tab()->ref.
key];
143 return &key->key_part[field_no];
151 return get_join_tab()->table;
154 double Table_access::get_fanout()
const
163 DBUG_ASSERT(get_join_tab()->position);
164 DBUG_ASSERT(get_join_tab()->position->records_read>0.0);
165 return get_join_tab()->
position->records_read;
170 DBUG_ASSERT(get_join_tab()->position);
171 DBUG_ASSERT(get_join_tab()->position->records_read>0.0);
172 return get_join_tab()->
position->records_read;
175 DBUG_ASSERT(get_join_tab()->
table->file->stats.records>0.0);
176 return static_cast<double>(get_join_tab()->table->file->stats.records);
184 const JOIN_TAB* Table_access::get_join_tab()
const
186 return m_join_plan->get_join_tab(m_tab_no);
193 DBUG_ASSERT(field_item->type() == Item::FIELD_ITEM);
195 COND_EQUAL*
const cond_equal = get_join_tab()->join->cond_equal;
196 if (cond_equal!=NULL)
198 return (field_item->item_equal != NULL)
199 ? field_item->item_equal
210 DBUG_PRINT(
"info", (
"type:%d", get_join_tab()->
type));
211 DBUG_PRINT(
"info", (
"ref.key:%d", get_join_tab()->ref.key));
212 DBUG_PRINT(
"info", (
"ref.key_parts:%d", get_join_tab()->ref.key_parts));
213 DBUG_PRINT(
"info", (
"ref.key_length:%d", get_join_tab()->ref.key_length));
215 DBUG_PRINT(
"info", (
"order:%p", get_join_tab()->join->order.order));
216 DBUG_PRINT(
"info", (
"skip_sort_order:%d",
217 get_join_tab()->join->skip_sort_order));
218 DBUG_PRINT(
"info", (
"no_order:%d", get_join_tab()->join->no_order));
219 DBUG_PRINT(
"info", (
"simple_order:%d", get_join_tab()->join->simple_order));
221 DBUG_PRINT(
"info", (
"group:%d", get_join_tab()->join->group));
222 DBUG_PRINT(
"info", (
"group_list:%p", get_join_tab()->join->group_list.order));
223 DBUG_PRINT(
"info", (
"simple_group:%d", get_join_tab()->join->simple_group));
224 DBUG_PRINT(
"info", (
"group_optimized_away:%d",
225 get_join_tab()->join->group_optimized_away));
227 DBUG_PRINT(
"info", (
"full_join:%d", get_join_tab()->join->full_join));
228 DBUG_PRINT(
"info", (
"need_tmp:%d", get_join_tab()->join->need_tmp));
229 DBUG_PRINT(
"info", (
"select_distinct:%d",
230 get_join_tab()->join->select_distinct));
232 DBUG_PRINT(
"info", (
"use_quick:%d", get_join_tab()->use_quick));
233 DBUG_PRINT(
"info", (
"index:%d", get_join_tab()->
index));
234 DBUG_PRINT(
"info", (
"quick:%p", get_join_tab()->quick));
235 DBUG_PRINT(
"info", (
"select:%p", get_join_tab()->select));
236 if (get_join_tab()->select && get_join_tab()->select->quick)
238 DBUG_PRINT(
"info", (
"select->quick->get_type():%d",
239 get_join_tab()->select->quick->get_type()));
247 void Table_access::compute_type_and_index()
const
249 DBUG_ENTER(
"Table_access::compute_type_and_index");
250 const JOIN_TAB*
const join_tab= get_join_tab();
251 JOIN*
const join= join_tab->join;
258 if (join->group_list && !join->tmp_table_param.quick_group)
261 m_other_access_reason =
262 "GROUP BY cannot be done using index on grouped columns.";
271 DBUG_PRINT(
"info", (
"Operation %d is const-optimized.", m_tab_no));
279 switch (join_tab->type)
282 m_index_no= join_tab->ref.
key;
284 if (m_index_no == static_cast<int>(join_tab->table->s->primary_key))
286 DBUG_PRINT(
"info", (
"Operation %d is a primary key lookup.", m_tab_no));
291 DBUG_PRINT(
"info", (
"Operation %d is a unique index lookup.",
299 DBUG_ASSERT(join_tab->ref.
key >= 0);
300 DBUG_ASSERT((uint)join_tab->ref.
key < MAX_KEY);
301 m_index_no= join_tab->ref.
key;
306 const KEY *key_info= join_tab->table->s->key_info;
307 if (key_info[m_index_no].user_defined_key_parts ==
309 key_info[m_index_no].
flags & HA_NOSAME)
312 (m_index_no ==
static_cast<int32
>(join_tab->table->s->primary_key))
315 DBUG_PRINT(
"info", (
"Operation %d is an unique key referrence.", m_tab_no));
319 DBUG_ASSERT(join_tab->ref.
key_parts > 0);
323 DBUG_PRINT(
"info", (
"Operation %d is an ordered index scan.", m_tab_no));
328 DBUG_ASSERT(join_tab->
index < MAX_KEY);
329 m_index_no= join_tab->
index;
331 DBUG_PRINT(
"info", (
"Operation %d is an ordered index scan.", m_tab_no));
335 if (join_tab->use_quick == 2)
343 (
"Operation %d has 'use_quick == 2' -> not pushable",
350 if (join_tab->select != NULL &&
351 join_tab->select->quick != NULL)
364 const KEY *key_info= join_tab->table->s->key_info;
365 DBUG_EXECUTE(
"info", quick->dbug_dump(0, TRUE););
369 DBUG_ASSERT ((quick->index == MAX_KEY) ==
370 ((quick->get_type() == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE) ||
371 (quick->get_type() == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) ||
372 (quick->get_type() == QUICK_SELECT_I::QS_TYPE_ROR_UNION)));
375 if (quick->index == MAX_KEY)
377 m_index_no= join_tab->table->s->primary_key;
382 else if (quick->index == join_tab->table->s->primary_key)
384 m_index_no= quick->index;
385 if (key_info[m_index_no].algorithm == HA_KEY_ALG_HASH)
392 m_index_no= quick->index;
393 if (key_info[m_index_no].algorithm == HA_KEY_ALG_HASH)
401 DBUG_PRINT(
"info", (
"Operation %d is a table scan.", m_tab_no));
415 (
"Operation %d has join_type %d. -> Not pushable.",
416 m_tab_no, join_tab->type));
419 m_other_access_reason =
"This table access method can not be pushed.";
427 Table_access::Table_access()
431 m_other_access_reason(NULL),
457 const JOIN_TAB*
const join_tab= get_join_tab();
458 JOIN*
const join= join_tab->join;
476 else if (join->group_list && join->simple_group)
477 return (join->ordered_index_usage!=JOIN::ordered_index_group_by);
478 else if (join->
order && join->simple_order)
479 return (join->ordered_index_usage!=JOIN::ordered_index_order_by);