27
26
#include <drizzled/optimizer/access_method/scan.h>
28
27
#include <drizzled/util/test.h>
29
28
#include <drizzled/statistics_variables.h>
29
#include <drizzled/session.h>
31
31
using namespace drizzled;
33
33
static uint32_t make_join_orderinfo(Join *join);
35
bool optimizer::Scan::getStats(Table *table,
35
void optimizer::Scan::getStats(Table& table, JoinTable& join_tab)
38
Join *join= join_tab->join;
37
Join *join= join_tab.join;
39
38
bool statistics= test(! (join->select_options & SELECT_DESCRIBE));
40
39
uint64_t options= (join->select_options &
41
40
(SELECT_DESCRIBE | SELECT_NO_JOIN_CACHE)) |
43
42
uint32_t no_jbuf_after= make_join_orderinfo(join);
44
uint32_t index= join_tab - join->join_tab;
43
uint32_t index= &join_tab - join->join_tab;
47
46
* If previous table use cache
48
47
* If the incoming data set is already sorted don't use cache.
50
table->status= STATUS_NO_RECORD;
49
table.status= STATUS_NO_RECORD;
52
51
if (index != join->const_tables &&
53
52
! (options & SELECT_NO_JOIN_CACHE) &&
54
join_tab->use_quick != 2 &&
55
! join_tab->first_inner &&
53
join_tab.use_quick != 2 &&
54
! join_tab.first_inner &&
56
55
index <= no_jbuf_after &&
57
! join_tab->insideout_match_tab)
56
! join_tab.insideout_match_tab)
59
58
if ((options & SELECT_DESCRIBE) ||
60
59
! join_init_cache(join->session,
61
60
join->join_tab + join->const_tables,
62
61
index - join->const_tables))
64
join_tab[-1].next_select= sub_select_cache; /* Patch previous */
63
(&join_tab)[-1].next_select= sub_select_cache; /* Patch previous */
68
67
/* These init changes read_record */
69
if (join_tab->use_quick == 2)
68
if (join_tab.use_quick == 2)
71
70
join->session->server_status|= SERVER_QUERY_NO_GOOD_INDEX_USED;
72
join_tab->read_first_record= join_init_quick_read_record;
71
join_tab.read_first_record= join_init_quick_read_record;
75
74
join->session->status_var.select_range_check_count++;
80
join_tab->read_first_record= join_init_read_record;
79
join_tab.read_first_record= join_init_read_record;
81
80
if (index == join->const_tables)
83
if (join_tab->select && join_tab->select->quick)
82
if (join_tab.select && join_tab.select->quick)
87
85
join->session->status_var.select_range_count++;
92
89
join->session->server_status|= SERVER_QUERY_NO_INDEX_USED;
95
91
join->session->status_var.select_scan_count++;
101
if (join_tab->select && join_tab->select->quick)
96
if (join_tab.select && join_tab.select->quick)
105
99
join->session->status_var.select_full_range_join_count++;
110
103
join->session->server_status|= SERVER_QUERY_NO_INDEX_USED;
113
105
join->session->status_var.select_full_join_count++;
117
if (! table->no_keyread)
108
if (! table.no_keyread)
119
if (join_tab->select &&
120
join_tab->select->quick &&
121
join_tab->select->quick->index != MAX_KEY && //not index_merge
122
table->covering_keys.test(join_tab->select->quick->index))
110
if (join_tab.select &&
111
join_tab.select->quick &&
112
join_tab.select->quick->index != MAX_KEY && //not index_merge
113
table.covering_keys.test(join_tab.select->quick->index))
125
table->cursor->extra(HA_EXTRA_KEYREAD);
116
table.cursor->extra(HA_EXTRA_KEYREAD);
127
else if (! table->covering_keys.none() &&
128
! (join_tab->select && join_tab->select->quick))
118
else if (! table.covering_keys.none() && ! (join_tab.select && join_tab.select->quick))
129
119
{ // Only read index tree
130
if (! join_tab->insideout_match_tab)
120
if (! join_tab.insideout_match_tab)
133
123
See bug #26447: "Using the clustered index for a table scan
134
124
is always faster than using a secondary index".
136
if (table->getShare()->hasPrimaryKey() &&
137
table->cursor->primary_key_is_clustered())
126
if (table.getShare()->hasPrimaryKey() &&
127
table.cursor->primary_key_is_clustered())
139
join_tab->index= table->getShare()->getPrimaryKey();
129
join_tab.index= table.getShare()->getPrimaryKey();
143
join_tab->index= table->find_shortest_key(&table->covering_keys);
133
join_tab.index= table.find_shortest_key(&table.covering_keys);
146
join_tab->read_first_record= join_read_first;
147
join_tab->type= AM_NEXT; // Read with index_first / index_next
136
join_tab.read_first_record= join_read_first;
137
join_tab.type= AM_NEXT; // Read with index_first / index_next
164
152
static uint32_t make_join_orderinfo(Join *join)
167
154
if (join->need_tmp)
169
155
return join->tables;
172
for (i= join->const_tables ; i < join->tables ; i++)
157
uint32_t i= join->const_tables;
158
for (; i < join->tables; i++)
174
160
JoinTable *tab= join->join_tab + i;
175
161
Table *table= tab->table;