=== modified file 'sql/sql_select.cc' --- sql/sql_select.cc 2013-03-29 02:18:36 +0000 +++ sql/sql_select.cc 2013-03-31 22:59:12 +0000 @@ -1041,6 +1041,24 @@ JOIN::optimize() MEMROOT for prepared statements and stored procedures. */ + if (!thd->lex->describe && + conds && + select_lex && + select_lex->table_list.first && + select_lex->table_list.first->table && + conds->used_tables() && + conds->used_tables() == select_lex->table_list.first->table->map && + select_lex->table_list.first->table->s->tmp_table != NO_TMP_TABLE && + select_lex->table_list.first->derived == 0 && + select_lex->table_list.first->view == 0) + { + COND_STATISTIC cond= {conds, 0}; + List li; + li.push_back(&cond); + check_selectivity(thd, 10, select_lex->table_list.first->table, &li); + li.empty(); + } + Query_arena *arena= thd->stmt_arena, backup; if (arena->is_conventional()) arena= 0; // For easier test @@ -23398,6 +23416,78 @@ uint get_index_for_order(ORDER *order, T return MAX_KEY; } +/* + Count how much times conditions are true for several first rows of the table + + @param thd thread handle + @param rows_to_read how much rows to check + @param table table which should be checked + @conds conds list of conditions and countars for them + + @return number of really checked rows or 0 in case of error or empty table +*/ + +ulong check_selectivity(THD *thd, + ulong rows_to_read, + TABLE *table, + List *conds) +{ + ulong count= 0; + COND_STATISTIC *cond; + List_iterator_fast it(*conds); + handler *file= table->file; + uchar *record= table->record[0]; + int error= 0; + DBUG_ENTER("check_selectivity"); + + DBUG_ASSERT(rows_to_read > 0); + while ((cond= it++)) + { + DBUG_ASSERT(cond->cond); + DBUG_ASSERT(cond->cond->used_tables() == table->map); + cond->positive= 0; + } + it.rewind(); + + if (file->ha_rnd_init_with_error(1)) + DBUG_RETURN(0); + do + { + error= file->ha_rnd_next(record); + + if (thd->killed) + { + thd->send_kill_message(); + count= 0; + goto err; + } + if (error) + { + if (error == HA_ERR_RECORD_DELETED) + continue; + if (error == HA_ERR_END_OF_FILE) + break; + goto err; + } + + count++; + while ((cond= it++)) + { + if (cond->cond->val_bool()) + cond->positive++; + } + it.rewind(); + + } while (count < rows_to_read); + + file->ha_rnd_end(); + DBUG_RETURN(count); + +err: + DBUG_PRINT("error", ("error %d", error)); + file->ha_rnd_end(); + DBUG_RETURN(0); +} /** @} (end of group Query_Optimizer) === modified file 'sql/sql_select.h' --- sql/sql_select.h 2013-02-28 21:47:29 +0000 +++ sql/sql_select.h 2013-03-31 22:13:35 +0000 @@ -1823,4 +1823,16 @@ void setup_tmp_table_column_bitmaps(TABL double prev_record_reads(POSITION *positions, uint idx, table_map found_ref); void fix_list_after_tbl_changes(SELECT_LEX *new_parent, List *tlist); +struct st_cond_statistic +{ + Item *cond; + ulong positive; +}; +typedef struct st_cond_statistic COND_STATISTIC; + +ulong check_selectivity(THD *thd, + ulong rows_to_read, + TABLE *table, + List *conds); + #endif /* SQL_SELECT_INCLUDED */