20
select_query and join optimization
20
mysql_select and join optimization
22
22
@defgroup Query_Optimizer Query Optimizer
28
28
#include <iostream>
29
29
#include <algorithm>
32
#include <drizzled/sql_select.h> /* include join.h */
34
#include <drizzled/error.h>
35
#include <drizzled/gettext.h>
36
#include <drizzled/util/test.h>
37
#include <drizzled/name_resolution_context_state.h>
38
#include <drizzled/nested_join.h>
39
#include <drizzled/probes.h>
40
#include <drizzled/show.h>
41
#include <drizzled/item/cache.h>
42
#include <drizzled/item/cmpfunc.h>
43
#include <drizzled/item/copy_string.h>
44
#include <drizzled/item/uint.h>
45
#include <drizzled/cached_item.h>
46
#include <drizzled/sql_base.h>
47
#include <drizzled/field/blob.h>
48
#include <drizzled/check_stack_overrun.h>
49
#include <drizzled/lock.h>
50
#include <drizzled/item/outer_ref.h>
51
#include <drizzled/index_hint.h>
52
#include <drizzled/records.h>
53
#include <drizzled/internal/iocache.h>
54
#include <drizzled/drizzled.h>
55
#include <drizzled/plugin/storage_engine.h>
57
#include <drizzled/sql_union.h>
58
#include <drizzled/optimizer/key_field.h>
59
#include <drizzled/optimizer/position.h>
60
#include <drizzled/optimizer/sargable_param.h>
61
#include <drizzled/optimizer/key_use.h>
62
#include <drizzled/optimizer/range.h>
63
#include <drizzled/optimizer/quick_range_select.h>
64
#include <drizzled/optimizer/quick_ror_intersect_select.h>
66
#include <drizzled/filesort.h>
67
#include <drizzled/sql_lex.h>
68
#include <drizzled/session.h>
69
#include <drizzled/sort_field.h>
70
#include <drizzled/select_result.h>
32
#include "drizzled/sql_select.h" /* include join.h */
34
#include "drizzled/error.h"
35
#include "drizzled/gettext.h"
36
#include "drizzled/util/test.h"
37
#include "drizzled/name_resolution_context_state.h"
38
#include "drizzled/nested_join.h"
39
#include "drizzled/probes.h"
40
#include "drizzled/show.h"
41
#include "drizzled/item/cache.h"
42
#include "drizzled/item/cmpfunc.h"
43
#include "drizzled/item/copy_string.h"
44
#include "drizzled/item/uint.h"
45
#include "drizzled/cached_item.h"
46
#include "drizzled/sql_base.h"
47
#include "drizzled/field/blob.h"
48
#include "drizzled/check_stack_overrun.h"
49
#include "drizzled/lock.h"
50
#include "drizzled/item/outer_ref.h"
51
#include "drizzled/index_hint.h"
52
#include "drizzled/records.h"
53
#include "drizzled/internal/iocache.h"
54
#include "drizzled/drizzled.h"
56
#include "drizzled/sql_union.h"
57
#include "drizzled/optimizer/key_field.h"
58
#include "drizzled/optimizer/position.h"
59
#include "drizzled/optimizer/sargable_param.h"
60
#include "drizzled/optimizer/key_use.h"
61
#include "drizzled/optimizer/range.h"
62
#include "drizzled/optimizer/quick_range_select.h"
63
#include "drizzled/optimizer/quick_ror_intersect_select.h"
65
#include "drizzled/filesort.h"
72
67
using namespace std;
136
131
unit->set_limit(unit->global_parameters);
137
132
session->session_marker= 0;
139
'options' of select_query will be set in JOIN, as far as JOIN for
134
'options' of mysql_select will be set in JOIN, as far as JOIN for
140
135
every PS/SP execution new, we will not need reset this flag if
141
136
setup_tables_done_option changed for next rexecution
143
res= select_query(session,
144
&select_lex->ref_pointer_array,
138
res= mysql_select(session, &select_lex->ref_pointer_array,
145
139
(TableList*) select_lex->table_list.first,
146
select_lex->with_wild,
147
select_lex->item_list,
140
select_lex->with_wild, select_lex->item_list,
148
141
select_lex->where,
149
142
select_lex->order_list.elements +
150
143
select_lex->group_list.elements,
1905
1899
Item_cond_and *and_cond= new Item_cond_and(eq_list);
1906
1900
and_cond->quick_fix_field();
1907
1901
List<Item> *args= and_cond->argument_list();
1908
List<Item_equal>::iterator it(cond_equal.current_level.begin());
1902
List_iterator_fast<Item_equal> it(cond_equal.current_level);
1909
1903
while ((item_equal= it++))
1911
1905
item_equal->fix_length_and_dec();
1912
1906
item_equal->update_used_tables();
1913
set_if_bigger(session->getLex()->current_select->max_equal_elems,
1907
set_if_bigger(session->lex->current_select->max_equal_elems,
1914
1908
item_equal->members());
1916
1910
and_cond->cond_equal= cond_equal;
2476
2469
static void propagate_cond_constants(Session *session,
2477
list<COND_CMP>& save_list,
2470
vector<COND_CMP>& save_list,
2478
2471
COND *and_father,
2481
2474
if (cond->type() == Item::COND_ITEM)
2483
2476
bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
2484
List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
2477
List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
2486
list<COND_CMP> save;
2479
vector<COND_CMP> save;
2487
2480
while ((item=li++))
2489
2482
propagate_cond_constants(session, save, and_level ? cond : item, item);
2493
2486
// Handle other found items
2494
for (list<COND_CMP>::iterator iter= save.begin(); iter != save.end(); ++iter)
2487
for (vector<COND_CMP>::iterator iter= save.begin(); iter != save.end(); ++iter)
2496
Item **args= iter->second->arguments();
2497
if (not args[0]->const_item())
2489
Item **args= iter->cmp_func->arguments();
2490
if (!args[0]->const_item())
2499
change_cond_ref_to_const(session, save, iter->first,
2500
iter->first, args[0], args[1] );
2492
change_cond_ref_to_const( session, save, iter->and_level,
2493
iter->and_level, args[0], args[1] );
3359
int join_read_const_table(JoinTable *tab, optimizer::Position *pos)
3362
Table *table=tab->table;
3363
table->const_table=1;
3365
table->status=STATUS_NO_RECORD;
3367
if (tab->type == AM_SYSTEM)
3369
if ((error=join_read_system(tab)))
3370
{ // Info for DESCRIBE
3371
tab->info="const row not found";
3372
/* Mark for EXPLAIN that the row was not found */
3373
pos->setFanout(0.0);
3374
pos->clearRefDependMap();
3375
if (! table->maybe_null || error > 0)
3381
if (! table->key_read &&
3382
table->covering_keys.test(tab->ref.key) &&
3383
! table->no_keyread &&
3384
(int) table->reginfo.lock_type <= (int) TL_READ_WITH_SHARED_LOCKS)
3387
table->cursor->extra(HA_EXTRA_KEYREAD);
3388
tab->index= tab->ref.key;
3390
error=join_read_const(tab);
3391
if (table->key_read)
3394
table->cursor->extra(HA_EXTRA_NO_KEYREAD);
3398
tab->info="unique row not found";
3399
/* Mark for EXPLAIN that the row was not found */
3400
pos->setFanout(0.0);
3401
pos->clearRefDependMap();
3402
if (!table->maybe_null || error > 0)
3406
if (*tab->on_expr_ref && !table->null_row)
3408
if ((table->null_row= test((*tab->on_expr_ref)->val_int() == 0)))
3409
table->mark_as_null_row();
3411
if (!table->null_row)
3412
table->maybe_null=0;
3414
/* Check appearance of new constant items in Item_equal objects */
3415
Join *join= tab->join;
3417
update_const_equal_items(join->conds, tab);
3419
for (tbl= join->select_lex->leaf_tables; tbl; tbl= tbl->next_leaf)
3421
TableList *embedded;
3422
TableList *embedding= tbl;
3425
embedded= embedding;
3426
if (embedded->on_expr)
3427
update_const_equal_items(embedded->on_expr, tab);
3428
embedding= embedded->getEmbedding();
3431
embedding->getNestedJoin()->join_list.head() == embedded);
3437
int join_read_system(JoinTable *tab)
3439
Table *table= tab->table;
3441
if (table->status & STATUS_GARBAGE) // If first read
3443
if ((error=table->cursor->read_first_row(table->getInsertRecord(),
3444
table->getShare()->getPrimaryKey())))
3446
if (error != HA_ERR_END_OF_FILE)
3447
return table->report_error(error);
3448
tab->table->mark_as_null_row();
3449
table->emptyRecord(); // Make empty record
3452
table->storeRecord();
3454
else if (!table->status) // Only happens with left join
3455
table->restoreRecord(); // restore old record
3457
return table->status ? -1 : 0;
3375
3461
Read a (constant) table when there is at most one matching row.