diff options
-rw-r--r-- | merge/open.c | 8 | ||||
-rw-r--r-- | myisammrg/myrg_open.c | 8 | ||||
-rw-r--r-- | sql/sql_select.cc | 64 |
3 files changed, 52 insertions, 28 deletions
diff --git a/merge/open.c b/merge/open.c index 35005e6e718..05f194b42d4 100644 --- a/merge/open.c +++ b/merge/open.c @@ -36,7 +36,7 @@ int mode; int handle_locking; { int save_errno,i,errpos; - uint files,dir_length,length; + uint files,dir_length,length, options; ulonglong file_offset; char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end; MRG_INFO info,*m_info; @@ -90,16 +90,22 @@ int handle_locking; m_info->open_tables=(MRG_TABLE *) (m_info+1); m_info->tables=files; + options= (uint) ~0; for (i=files ; i-- > 0 ; ) { m_info->open_tables[i].table=isam; m_info->options|=isam->s->base.options; + options&=isam->s->base.options; m_info->records+=isam->s->state.records; m_info->del+=isam->s->state.del; m_info->data_file_length=isam->s->state.data_file_length; if (i) isam=(N_INFO*) (isam->open_list.next->data); } + /* Don't force readonly if not all tables are readonly */ + if (! (options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA))) + m_info->options&= ~(HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA); + /* Fix fileinfo for easyer debugging (actually set by rrnd) */ file_offset=0; for (i=0 ; (uint) i < files ; i++) diff --git a/myisammrg/myrg_open.c b/myisammrg/myrg_open.c index f73339f63c8..ce2c97e1276 100644 --- a/myisammrg/myrg_open.c +++ b/myisammrg/myrg_open.c @@ -36,7 +36,7 @@ int mode; int handle_locking; { int save_errno,i,errpos; - uint files,dir_length,length; + uint files,dir_length,length,options; ulonglong file_offset; char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end; MYRG_INFO info,*m_info; @@ -93,16 +93,22 @@ int handle_locking; m_info->tables=files; errpos=2; + options= (uint) ~0; for (i=files ; i-- > 0 ; ) { m_info->open_tables[i].table=isam; m_info->options|=isam->s->options; + options&=isam->s->options; m_info->records+=isam->state->records; m_info->del+=isam->state->del; m_info->data_file_length+=isam->state->data_file_length; if (i) isam=(MI_INFO*) (isam->open_list.next->data); } + /* Don't force readonly if not all tables are readonly */ + if (! (options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA))) + m_info->options&= ~(HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA); + /* Fix fileinfo for easyer debugging (actually set by rrnd) */ file_offset=0; for (i=0 ; (uint) i < files ; i++) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 2f417fc2618..cd6ff415070 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -104,7 +104,7 @@ static COND *make_cond_for_table(COND *cond,table_map table, static Item* part_of_refkey(TABLE *form,Field *field); static uint find_shortest_key(TABLE *table, key_map usable_keys); static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order, - ha_rows select_limit); + ha_rows select_limit, bool no_changes); static int create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit); static int remove_duplicates(JOIN *join,TABLE *entry,List<Item> &fields); static int remove_dup_with_compare(THD *thd, TABLE *entry, Field **field, @@ -154,7 +154,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, TABLE *tmp_table; int error,tmp; bool need_tmp,hidden_group_fields; - bool simple_order,simple_group,no_order; + bool simple_order,simple_group,no_order, skip_sort_order; Item::cond_result cond_value; SQL_SELECT *select; DYNAMIC_ARRAY keyuse; @@ -169,7 +169,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, select_distinct=test(select_options & SELECT_DISTINCT); tmp_table=0; select=0; - no_order=0; + no_order=skip_sort_order=0; bzero((char*) &keyuse,sizeof(keyuse)); thd->proc_info="init"; thd->used_tables=0; // Updated by setup_fields @@ -433,8 +433,10 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, select_distinct=0; } else if (select_distinct && join.tables - join.const_tables == 1 && - (order || thd->select_limit == HA_POS_ERROR || - (join.select_options & OPTION_FOUND_ROWS))) + (thd->select_limit == HA_POS_ERROR || + (join.select_options & OPTION_FOUND_ROWS) || + order && + !(skip_sort_order=test_if_skip_sort_order(&join.join_tab[join.const_tables], order, thd->select_limit,1)))) { if ((group=create_distinct_group(order,fields))) { @@ -518,7 +520,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, if (!(select_options & SELECT_BIG_RESULT) && ((group && join.const_tables != join.tables && !test_if_skip_sort_order(&join.join_tab[join.const_tables], group, - HA_POS_ERROR)) || + thd->select_limit,0)) || select_distinct) && join.tmp_table_param.quick_group && !procedure) { @@ -532,10 +534,9 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, if (order && (join.const_tables == join.tables || test_if_skip_sort_order(&join.join_tab[join.const_tables], order, - (having || group || - join.const_tables != join.tables - 1 || + (join.const_tables != join.tables - 1 || (join.select_options & OPTION_FOUND_ROWS)) ? - HA_POS_ERROR : thd->select_limit))) + HA_POS_ERROR : thd->select_limit,0))) order=0; select_describe(&join,need_tmp, (order != 0 && @@ -571,7 +572,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, group : (ORDER*) 0), group ? 0 : select_distinct, group && simple_group, - order == 0 && + (order == 0 || skip_sort_order) && !(join.select_options & OPTION_FOUND_ROWS), join.select_options))) goto err; /* purecov: inspected */ @@ -622,6 +623,13 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, break; join_tab->not_used_in_distinct=1; } while (join_tab-- != join.join_tab); + /* Optimize "select distinct b from t1 order by key_part_1 limit #" */ + if (order && skip_sort_order) + { + (void) test_if_skip_sort_order(&join.join_tab[join.const_tables], + order, thd->select_limit,0); + order=0; + } } /* Copy data to the temporary table */ @@ -4757,15 +4765,15 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (create_myisam_from_heap(table, &join->tmp_table_param, error,1)) DBUG_RETURN(1); // Not a table_is_full error table->uniques=0; // To ensure rows are the same - if (++join->send_records >= join->tmp_table_param.end_write_records & - join->do_send_rows) - { - if (!(join->select_options & OPTION_FOUND_ROWS)) - DBUG_RETURN(-3); - join->do_send_rows=0; - join->thd->select_limit = HA_POS_ERROR; - DBUG_RETURN(0); - } + } + if (++join->send_records >= join->tmp_table_param.end_write_records & + join->do_send_rows) + { + if (!(join->select_options & OPTION_FOUND_ROWS)) + DBUG_RETURN(-3); + join->do_send_rows=0; + join->thd->select_limit = HA_POS_ERROR; + DBUG_RETURN(0); } } } @@ -5162,7 +5170,8 @@ static uint find_shortest_key(TABLE *table, key_map usable_keys) /* Return 1 if we don't have to do file sorting */ static bool -test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit) +test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, + bool no_changes) { int ref_key; TABLE *table=tab->table; @@ -5217,11 +5226,14 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit) int flag; if ((flag=test_if_order_by_key(order,table,nr))) { - tab->index=nr; - tab->read_first_record= (flag > 0 ? join_init_read_first_with_key: - join_init_read_last_with_key); - table->file->index_init(nr); - tab->type=JT_NEXT; // Read with index_first(), index_next() + if (!no_changes) + { + tab->index=nr; + tab->read_first_record= (flag > 0 ? join_init_read_first_with_key: + join_init_read_last_with_key); + table->file->index_init(nr); + tab->type=JT_NEXT; // Read with index_first(), index_next() + } DBUG_RETURN(1); } } @@ -5239,7 +5251,7 @@ create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit) SQL_SELECT *select=tab->select; DBUG_ENTER("create_sort_index"); - if (test_if_skip_sort_order(tab,order,select_limit)) + if (test_if_skip_sort_order(tab,order,select_limit,0)) DBUG_RETURN(0); if (!(sortorder=make_unireg_sortorder(order,&length))) goto err; /* purecov: inspected */ |