Commit e5f9ca3d authored by unknown's avatar unknown

Only mark MERGE readonly if all tables are readonly

Optimize some queries when using LIMIT


merge/open.c:
  Only mark MERGE readonly if all tables are readonly
myisammrg/myrg_open.c:
  Only mark MERGE readonly if all tables are readonly
sql/sql_select.cc:
  Optimize some queries when using LIMIT
parent dbd56fcd
...@@ -36,7 +36,7 @@ int mode; ...@@ -36,7 +36,7 @@ int mode;
int handle_locking; int handle_locking;
{ {
int save_errno,i,errpos; int save_errno,i,errpos;
uint files,dir_length,length; uint files,dir_length,length, options;
ulonglong file_offset; ulonglong file_offset;
char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end; char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end;
MRG_INFO info,*m_info; MRG_INFO info,*m_info;
...@@ -90,16 +90,22 @@ int handle_locking; ...@@ -90,16 +90,22 @@ int handle_locking;
m_info->open_tables=(MRG_TABLE *) (m_info+1); m_info->open_tables=(MRG_TABLE *) (m_info+1);
m_info->tables=files; m_info->tables=files;
options= (uint) ~0;
for (i=files ; i-- > 0 ; ) for (i=files ; i-- > 0 ; )
{ {
m_info->open_tables[i].table=isam; m_info->open_tables[i].table=isam;
m_info->options|=isam->s->base.options; m_info->options|=isam->s->base.options;
options&=isam->s->base.options;
m_info->records+=isam->s->state.records; m_info->records+=isam->s->state.records;
m_info->del+=isam->s->state.del; m_info->del+=isam->s->state.del;
m_info->data_file_length=isam->s->state.data_file_length; m_info->data_file_length=isam->s->state.data_file_length;
if (i) if (i)
isam=(N_INFO*) (isam->open_list.next->data); 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) */ /* Fix fileinfo for easyer debugging (actually set by rrnd) */
file_offset=0; file_offset=0;
for (i=0 ; (uint) i < files ; i++) for (i=0 ; (uint) i < files ; i++)
......
...@@ -36,7 +36,7 @@ int mode; ...@@ -36,7 +36,7 @@ int mode;
int handle_locking; int handle_locking;
{ {
int save_errno,i,errpos; int save_errno,i,errpos;
uint files,dir_length,length; uint files,dir_length,length,options;
ulonglong file_offset; ulonglong file_offset;
char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end; char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end;
MYRG_INFO info,*m_info; MYRG_INFO info,*m_info;
...@@ -93,16 +93,22 @@ int handle_locking; ...@@ -93,16 +93,22 @@ int handle_locking;
m_info->tables=files; m_info->tables=files;
errpos=2; errpos=2;
options= (uint) ~0;
for (i=files ; i-- > 0 ; ) for (i=files ; i-- > 0 ; )
{ {
m_info->open_tables[i].table=isam; m_info->open_tables[i].table=isam;
m_info->options|=isam->s->options; m_info->options|=isam->s->options;
options&=isam->s->options;
m_info->records+=isam->state->records; m_info->records+=isam->state->records;
m_info->del+=isam->state->del; m_info->del+=isam->state->del;
m_info->data_file_length+=isam->state->data_file_length; m_info->data_file_length+=isam->state->data_file_length;
if (i) if (i)
isam=(MI_INFO*) (isam->open_list.next->data); 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) */ /* Fix fileinfo for easyer debugging (actually set by rrnd) */
file_offset=0; file_offset=0;
for (i=0 ; (uint) i < files ; i++) for (i=0 ; (uint) i < files ; i++)
......
...@@ -104,7 +104,7 @@ static COND *make_cond_for_table(COND *cond,table_map table, ...@@ -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 Item* part_of_refkey(TABLE *form,Field *field);
static uint find_shortest_key(TABLE *table, key_map usable_keys); static uint find_shortest_key(TABLE *table, key_map usable_keys);
static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order, 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 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_duplicates(JOIN *join,TABLE *entry,List<Item> &fields);
static int remove_dup_with_compare(THD *thd, TABLE *entry, Field **field, 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, ...@@ -154,7 +154,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
TABLE *tmp_table; TABLE *tmp_table;
int error,tmp; int error,tmp;
bool need_tmp,hidden_group_fields; 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; Item::cond_result cond_value;
SQL_SELECT *select; SQL_SELECT *select;
DYNAMIC_ARRAY keyuse; DYNAMIC_ARRAY keyuse;
...@@ -169,7 +169,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -169,7 +169,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
select_distinct=test(select_options & SELECT_DISTINCT); select_distinct=test(select_options & SELECT_DISTINCT);
tmp_table=0; tmp_table=0;
select=0; select=0;
no_order=0; no_order=skip_sort_order=0;
bzero((char*) &keyuse,sizeof(keyuse)); bzero((char*) &keyuse,sizeof(keyuse));
thd->proc_info="init"; thd->proc_info="init";
thd->used_tables=0; // Updated by setup_fields thd->used_tables=0; // Updated by setup_fields
...@@ -433,8 +433,10 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -433,8 +433,10 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
select_distinct=0; select_distinct=0;
} }
else if (select_distinct && join.tables - join.const_tables == 1 && else if (select_distinct && join.tables - join.const_tables == 1 &&
(order || thd->select_limit == HA_POS_ERROR || (thd->select_limit == HA_POS_ERROR ||
(join.select_options & OPTION_FOUND_ROWS))) (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))) if ((group=create_distinct_group(order,fields)))
{ {
...@@ -518,7 +520,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -518,7 +520,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
if (!(select_options & SELECT_BIG_RESULT) && if (!(select_options & SELECT_BIG_RESULT) &&
((group && join.const_tables != join.tables && ((group && join.const_tables != join.tables &&
!test_if_skip_sort_order(&join.join_tab[join.const_tables], group, !test_if_skip_sort_order(&join.join_tab[join.const_tables], group,
HA_POS_ERROR)) || thd->select_limit,0)) ||
select_distinct) && select_distinct) &&
join.tmp_table_param.quick_group && !procedure) join.tmp_table_param.quick_group && !procedure)
{ {
...@@ -532,10 +534,9 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -532,10 +534,9 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
if (order && if (order &&
(join.const_tables == join.tables || (join.const_tables == join.tables ||
test_if_skip_sort_order(&join.join_tab[join.const_tables], order, 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)) ? (join.select_options & OPTION_FOUND_ROWS)) ?
HA_POS_ERROR : thd->select_limit))) HA_POS_ERROR : thd->select_limit,0)))
order=0; order=0;
select_describe(&join,need_tmp, select_describe(&join,need_tmp,
(order != 0 && (order != 0 &&
...@@ -571,7 +572,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -571,7 +572,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
group : (ORDER*) 0), group : (ORDER*) 0),
group ? 0 : select_distinct, group ? 0 : select_distinct,
group && simple_group, group && simple_group,
order == 0 && (order == 0 || skip_sort_order) &&
!(join.select_options & OPTION_FOUND_ROWS), !(join.select_options & OPTION_FOUND_ROWS),
join.select_options))) join.select_options)))
goto err; /* purecov: inspected */ goto err; /* purecov: inspected */
...@@ -622,6 +623,13 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -622,6 +623,13 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
break; break;
join_tab->not_used_in_distinct=1; join_tab->not_used_in_distinct=1;
} while (join_tab-- != join.join_tab); } 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 */ /* Copy data to the temporary table */
...@@ -4757,15 +4765,15 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), ...@@ -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)) if (create_myisam_from_heap(table, &join->tmp_table_param, error,1))
DBUG_RETURN(1); // Not a table_is_full error DBUG_RETURN(1); // Not a table_is_full error
table->uniques=0; // To ensure rows are the same 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->send_records >= join->tmp_table_param.end_write_records &
{ join->do_send_rows)
if (!(join->select_options & OPTION_FOUND_ROWS)) {
DBUG_RETURN(-3); if (!(join->select_options & OPTION_FOUND_ROWS))
join->do_send_rows=0; DBUG_RETURN(-3);
join->thd->select_limit = HA_POS_ERROR; join->do_send_rows=0;
DBUG_RETURN(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) ...@@ -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 */ /* Return 1 if we don't have to do file sorting */
static bool 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; int ref_key;
TABLE *table=tab->table; TABLE *table=tab->table;
...@@ -5217,11 +5226,14 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit) ...@@ -5217,11 +5226,14 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
int flag; int flag;
if ((flag=test_if_order_by_key(order,table,nr))) if ((flag=test_if_order_by_key(order,table,nr)))
{ {
tab->index=nr; if (!no_changes)
tab->read_first_record= (flag > 0 ? join_init_read_first_with_key: {
join_init_read_last_with_key); tab->index=nr;
table->file->index_init(nr); tab->read_first_record= (flag > 0 ? join_init_read_first_with_key:
tab->type=JT_NEXT; // Read with index_first(), index_next() join_init_read_last_with_key);
table->file->index_init(nr);
tab->type=JT_NEXT; // Read with index_first(), index_next()
}
DBUG_RETURN(1); DBUG_RETURN(1);
} }
} }
...@@ -5239,7 +5251,7 @@ create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit) ...@@ -5239,7 +5251,7 @@ create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
SQL_SELECT *select=tab->select; SQL_SELECT *select=tab->select;
DBUG_ENTER("create_sort_index"); 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); DBUG_RETURN(0);
if (!(sortorder=make_unireg_sortorder(order,&length))) if (!(sortorder=make_unireg_sortorder(order,&length)))
goto err; /* purecov: inspected */ goto err; /* purecov: inspected */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment