1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Merge gkodinov@bk-internal.mysql.com:/home/bk/mysql-5.1-opt

into  magare.gmz:/home/kgeorge/mysql/autopush/WL3527-5.1-opt
This commit is contained in:
gkodinov/kgeorge@magare.gmz
2007-03-09 17:54:13 +02:00
22 changed files with 725 additions and 263 deletions

View File

@ -163,13 +163,15 @@ static COND *make_cond_for_table(COND *cond,table_map table,
static Item* part_of_refkey(TABLE *form,Field *field);
uint find_shortest_key(TABLE *table, const key_map *usable_keys);
static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,
ha_rows select_limit, bool no_changes);
ha_rows select_limit, bool no_changes,
key_map *map);
static bool list_contains_unique_index(TABLE *table,
bool (*find_func) (Field *, void *), void *data);
static bool find_field_in_item_list (Field *field, void *data);
static bool find_field_in_order_list (Field *field, void *data);
static int create_sort_index(THD *thd, JOIN *join, ORDER *order,
ha_rows filesort_limit, ha_rows select_limit);
ha_rows filesort_limit, ha_rows select_limit,
bool is_order_by);
static int remove_duplicates(JOIN *join,TABLE *entry,List<Item> &fields,
Item *having);
static int remove_dup_with_compare(THD *thd, TABLE *entry, Field **field,
@ -1024,14 +1026,15 @@ JOIN::optimize()
JOIN_TAB *tab= &join_tab[const_tables];
bool all_order_fields_used;
if (order)
skip_sort_order= test_if_skip_sort_order(tab, order, select_limit, 1);
skip_sort_order= test_if_skip_sort_order(tab, order, select_limit, 1,
&tab->table->keys_in_use_for_order_by);
if ((group_list=create_distinct_group(thd, select_lex->ref_pointer_array,
order, fields_list,
&all_order_fields_used)))
{
bool skip_group= (skip_sort_order &&
test_if_skip_sort_order(tab, group_list, select_limit,
1) != 0);
test_if_skip_sort_order(tab, group_list, select_limit, 1,
&tab->table->keys_in_use_for_group_by) != 0);
if ((skip_group && all_order_fields_used) ||
select_limit == HA_POS_ERROR ||
(order && !skip_sort_order))
@ -1229,7 +1232,9 @@ JOIN::optimize()
((group_list &&
(!simple_group ||
!test_if_skip_sort_order(&join_tab[const_tables], group_list,
unit->select_limit_cnt, 0))) ||
unit->select_limit_cnt, 0,
&join_tab[const_tables].table->
keys_in_use_for_group_by))) ||
select_distinct) &&
tmp_table_param.quick_group && !procedure)
{
@ -1331,7 +1336,7 @@ JOIN::optimize()
DBUG_PRINT("info",("Sorting for group"));
thd->proc_info="Sorting for group";
if (create_sort_index(thd, this, group_list,
HA_POS_ERROR, HA_POS_ERROR) ||
HA_POS_ERROR, HA_POS_ERROR, FALSE) ||
alloc_group_fields(this, group_list) ||
make_sum_func_list(all_fields, fields_list, 1) ||
setup_sum_funcs(thd, sum_funcs))
@ -1348,7 +1353,7 @@ JOIN::optimize()
DBUG_PRINT("info",("Sorting for order"));
thd->proc_info="Sorting for order";
if (create_sort_index(thd, this, order,
HA_POS_ERROR, HA_POS_ERROR))
HA_POS_ERROR, HA_POS_ERROR, TRUE))
DBUG_RETURN(1);
order=0;
}
@ -1375,7 +1380,9 @@ JOIN::optimize()
{
/* Should always succeed */
if (test_if_skip_sort_order(&join_tab[const_tables],
order, unit->select_limit_cnt, 0))
order, unit->select_limit_cnt, 0,
&join_tab[const_tables].table->
keys_in_use_for_order_by))
order=0;
}
}
@ -1568,7 +1575,9 @@ JOIN::exec()
(const_tables == tables ||
((simple_order || skip_sort_order) &&
test_if_skip_sort_order(&join_tab[const_tables], order,
select_limit, 0))))
select_limit, 0,
&join_tab[const_tables].table->
keys_in_use_for_order_by))))
order=0;
having= tmp_having;
select_describe(this, need_tmp,
@ -1744,7 +1753,7 @@ JOIN::exec()
DBUG_VOID_RETURN;
}
if (create_sort_index(thd, curr_join, curr_join->group_list,
HA_POS_ERROR, HA_POS_ERROR) ||
HA_POS_ERROR, HA_POS_ERROR, FALSE) ||
make_group_fields(this, curr_join))
{
DBUG_VOID_RETURN;
@ -1960,7 +1969,8 @@ JOIN::exec()
curr_join->group_list : curr_join->order,
curr_join->select_limit,
(select_options & OPTION_FOUND_ROWS ?
HA_POS_ERROR : unit->select_limit_cnt)))
HA_POS_ERROR : unit->select_limit_cnt),
curr_join->group_list ? TRUE : FALSE))
DBUG_VOID_RETURN;
sortorder= curr_join->sortorder;
if (curr_join->const_tables != curr_join->tables &&
@ -3964,7 +3974,7 @@ best_access_path(JOIN *join,
/* Limit the number of matched rows */
tmp= records;
set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
if (table->used_keys.is_set(key))
if (table->covering_keys.is_set(key))
{
/* we can use only index tree */
uint keys_per_block= table->file->stats.block_size/2/
@ -4131,7 +4141,7 @@ best_access_path(JOIN *join,
/* Limit the number of matched rows */
set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
if (table->used_keys.is_set(key))
if (table->covering_keys.is_set(key))
{
/* we can use only index tree */
uint keys_per_block= table->file->stats.block_size/2/
@ -4190,7 +4200,7 @@ best_access_path(JOIN *join,
!(s->quick && best_key && s->quick->index == best_key->key && // (2)
best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&// (2)
!((s->table->file->ha_table_flags() & HA_TABLE_SCAN_ON_INDEX) && // (3)
! s->table->used_keys.is_clear_all() && best_key) && // (3)
! s->table->covering_keys.is_clear_all() && best_key) && // (3)
!(s->table->force_index && best_key && !s->quick)) // (4)
{ // Check full join
ha_rows rnd_records= s->found_records;
@ -6098,7 +6108,7 @@ make_join_readinfo(JOIN *join, ulonglong options)
(table == join->sort_by_table &&
(!join->order || join->skip_sort_order ||
test_if_skip_sort_order(tab, join->order, join->select_limit,
1))
1, &table->keys_in_use_for_order_by))
) ||
(join->sort_by_table == (TABLE *) 1 && i != join->const_tables))
ordered_set= 1;
@ -6115,7 +6125,7 @@ make_join_readinfo(JOIN *join, ulonglong options)
table->status=STATUS_NO_RECORD;
tab->read_first_record= join_read_const;
tab->read_record.read_record= join_no_more_records;
if (table->used_keys.is_set(tab->ref.key) &&
if (table->covering_keys.is_set(tab->ref.key) &&
!table->no_keyread)
{
table->key_read=1;
@ -6133,7 +6143,7 @@ make_join_readinfo(JOIN *join, ulonglong options)
tab->quick=0;
tab->read_first_record= join_read_key;
tab->read_record.read_record= join_no_more_records;
if (table->used_keys.is_set(tab->ref.key) &&
if (table->covering_keys.is_set(tab->ref.key) &&
!table->no_keyread)
{
table->key_read=1;
@ -6150,7 +6160,7 @@ make_join_readinfo(JOIN *join, ulonglong options)
}
delete tab->quick;
tab->quick=0;
if (table->used_keys.is_set(tab->ref.key) &&
if (table->covering_keys.is_set(tab->ref.key) &&
!table->no_keyread)
{
table->key_read=1;
@ -6236,15 +6246,15 @@ make_join_readinfo(JOIN *join, ulonglong options)
{
if (tab->select && tab->select->quick &&
tab->select->quick->index != MAX_KEY && //not index_merge
table->used_keys.is_set(tab->select->quick->index))
table->covering_keys.is_set(tab->select->quick->index))
{
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
}
else if (!table->used_keys.is_clear_all() &&
else if (!table->covering_keys.is_clear_all() &&
!(tab->select && tab->select->quick))
{ // Only read index tree
tab->index=find_shortest_key(table, & table->used_keys);
tab->index=find_shortest_key(table, & table->covering_keys);
tab->read_first_record= join_read_first;
tab->type=JT_NEXT; // Read with index_first / index_next
}
@ -9378,7 +9388,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
table->copy_blobs= 1;
table->in_use= thd;
table->quick_keys.init();
table->used_keys.init();
table->covering_keys.init();
table->keys_in_use_for_query.init();
table->s= share;
@ -11003,7 +11013,7 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos)
}
else
{
if (!table->key_read && table->used_keys.is_set(tab->ref.key) &&
if (!table->key_read && table->covering_keys.is_set(tab->ref.key) &&
!table->no_keyread &&
(int) table->reginfo.lock_type <= (int) TL_READ_HIGH_PRIORITY)
{
@ -11310,7 +11320,7 @@ join_read_first(JOIN_TAB *tab)
{
int error;
TABLE *table=tab->table;
if (!table->key_read && table->used_keys.is_set(tab->index) &&
if (!table->key_read && table->covering_keys.is_set(tab->index) &&
!table->no_keyread)
{
table->key_read=1;
@ -11349,7 +11359,7 @@ join_read_last(JOIN_TAB *tab)
{
TABLE *table=tab->table;
int error;
if (!table->key_read && table->used_keys.is_set(tab->index) &&
if (!table->key_read && table->covering_keys.is_set(tab->index) &&
!table->no_keyread)
{
table->key_read=1;
@ -12373,7 +12383,7 @@ find_field_in_item_list (Field *field, void *data)
static bool
test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
bool no_changes)
bool no_changes, key_map *map)
{
int ref_key;
uint ref_key_parts;
@ -12390,7 +12400,16 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
Keys disabled by ALTER TABLE ... DISABLE KEYS should have already
been taken into account.
*/
DBUG_ASSERT(usable_keys.is_subset(table->s->keys_in_use));
usable_keys= *map;
/*
If there is a covering index, and we have IGNORE INDEX FOR GROUP/ORDER
and this index is used for the JOIN part, then we have to ignore the
IGNORE INDEX FOR GROUP/ORDER
*/
if (table->key_read ||
(table->covering_keys.is_set(tab->index) && !table->no_keyread))
usable_keys.set_bit (tab->index);
for (ORDER *tmp_order=order; tmp_order ; tmp_order=tmp_order->next)
{
@ -12448,8 +12467,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
If using index only read, only consider other possible index only
keys
*/
if (table->used_keys.is_set(ref_key))
usable_keys.intersect(table->used_keys);
if (table->covering_keys.is_set(ref_key))
usable_keys.intersect(table->covering_keys);
if ((new_ref_key= test_if_subkey(order, table, ref_key, ref_key_parts,
&usable_keys)) < MAX_KEY)
{
@ -12564,7 +12583,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
if (select_limit >= table->file->stats.records)
{
keys= *table->file->keys_to_use_for_scanning();
keys.merge(table->used_keys);
keys.merge(table->covering_keys);
/*
We are adding here also the index specified in FORCE INDEX clause,
@ -12592,7 +12611,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
tab->read_first_record= (flag > 0 ? join_read_first:
join_read_last);
tab->type=JT_NEXT; // Read with index_first(), index_next()
if (table->used_keys.is_set(nr))
if (table->covering_keys.is_set(nr))
{
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
@ -12618,6 +12637,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
filesort_limit Max number of rows that needs to be sorted
select_limit Max number of rows in final output
Used to decide if we should use index or not
is_order_by true if we are sorting on ORDER BY, false if GROUP BY
Used to decide if we should use index or not
IMPLEMENTATION
@ -12636,7 +12657,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
static int
create_sort_index(THD *thd, JOIN *join, ORDER *order,
ha_rows filesort_limit, ha_rows select_limit)
ha_rows filesort_limit, ha_rows select_limit,
bool is_order_by)
{
uint length= 0;
ha_rows examined_rows;
@ -12657,7 +12679,9 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
*/
if ((order != join->group_list ||
!(join->select_options & SELECT_BIG_RESULT)) &&
test_if_skip_sort_order(tab,order,select_limit,0))
test_if_skip_sort_order(tab,order,select_limit,0,
is_order_by ? &table->keys_in_use_for_order_by :
&table->keys_in_use_for_group_by))
DBUG_RETURN(0);
for (ORDER *ord= join->order; ord; ord= ord->next)
length++;
@ -15285,7 +15309,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
/* Build "Extra" field and add it to item_list. */
my_bool key_read=table->key_read;
if ((tab->type == JT_NEXT || tab->type == JT_CONST) &&
table->used_keys.is_set(tab->index))
table->covering_keys.is_set(tab->index))
key_read=1;
if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT &&
!((QUICK_ROR_INTERSECT_SELECT*)tab->select->quick)->need_to_fetch_row)