Index: storage/innobase/row/row0mysql.c =================================================================== --- storage/innobase/row/row0mysql.c (revision 1) +++ storage/innobase/row/row0mysql.c (working copy) @@ -947,6 +947,14 @@ return(prebuilt->ins_node->row); } +/* + * check whether need to update the statistacs + * */ +inline ibool check_need_update_statistics(dict_table_t* table, ulint counter) +{ + return (counter > 2000000000 + || ((ib_int64_t)counter > 16 + table->stat_n_rows / 16)); +} /*********************************************************************//** Updates the table modification counter and calculates new estimates for table and index statistics if necessary. */ @@ -956,6 +964,7 @@ /*============================*/ dict_table_t* table) /*!< in: table */ { + ibool need_check; ulint counter; counter = table->stat_modified_counter; @@ -968,12 +977,21 @@ We calculate statistics at most every 16th round, since we may have a counter table which is very small and updated very often. */ - if (counter > 2000000000 - || ((ib_int64_t)counter > 16 + table->stat_n_rows / 16)) { + need_check = check_need_update_statistics(table, counter); - dict_update_statistics(table, FALSE /* update even if stats - are initialized */); - } + if (need_check) + { + /*re-check under lock, to avoid unnecessary calling*/ + dict_table_stats_lock(table, RW_X_LATCH); + need_check = check_need_update_statistics(table, table->stat_modified_counter); + dict_table_stats_unlock(table, RW_X_LATCH); + + if (need_check) + { + dict_update_statistics(table, FALSE /* update even if stats + are initialized */); + } + } } /*********************************************************************//**