From cfa08e8dadefc00e9542953a4a672b3a34f34303 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 28 Jul 2011 17:10:29 +0300 Subject: Subquery cache going on disk management fix: Do not go on disk if hit rate is not good. sql/sql_expression_cache.cc: Do not go on disk if hit rate is not good. Local hit/miss counters added. sql/sql_expression_cache.h: Local hit/miss counters added. --- sql/sql_expression_cache.cc | 48 +++++++++++++++++++++++++++++++++++++++------ sql/sql_expression_cache.h | 2 ++ 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/sql/sql_expression_cache.cc b/sql/sql_expression_cache.cc index 6b7a51bfa1c..bb39df45e25 100644 --- a/sql/sql_expression_cache.cc +++ b/sql/sql_expression_cache.cc @@ -16,6 +16,17 @@ #include "mysql_priv.h" #include "sql_select.h" +/** + Minimum hit ration to proceed on disk if in memory table overflowed. + hit_rate = hit / (miss + hit); +*/ +#define EXPCACHE_MIN_HIT_RATE_FOR_DISK_TABLE 0.7 +/** + Minimum hit ratio to keep in memory table (do not switch cache off) + hit_rate = hit / (miss + hit); +*/ +#define EXPCACHE_MIN_HIT_RATE_FOR_MEM_TABLE 0.2 + /* Expression cache is used only for caching subqueries now, so its statistic variables we call subquery_cache*. @@ -26,7 +37,7 @@ Expression_cache_tmptable::Expression_cache_tmptable(THD *thd, List &dependants, Item *value) :cache_table(NULL), table_thd(thd), items(dependants), val(value), - inited (0) + hit(0), miss(0), inited (0) { DBUG_ENTER("Expression_cache_tmptable::Expression_cache_tmptable"); DBUG_VOID_RETURN; @@ -180,10 +191,12 @@ Expression_cache::result Expression_cache_tmptable::check_value(Item **value) if (res) { subquery_cache_miss++; + miss++; DBUG_RETURN(MISS); } subquery_cache_hit++; + hit++; *value= cached_result; DBUG_RETURN(Expression_cache::HIT); } @@ -224,12 +237,35 @@ my_bool Expression_cache_tmptable::put_value(Item *value) if ((error= cache_table->file->ha_write_tmp_row(cache_table->record[0]))) { /* create_myisam_from_heap will generate error if needed */ - if (cache_table->file->is_fatal_error(error, HA_CHECK_DUP) && - create_internal_tmp_table_from_heap(table_thd, cache_table, - cache_table_param.start_recinfo, - &cache_table_param.recinfo, - error, 1)) + if (cache_table->file->is_fatal_error(error, HA_CHECK_DUP)) goto err; + else + { + double hit_rate= ((double)hit / ((double)hit + miss)); + DBUG_ASSERT(miss > 0); + if (hit_rate < EXPCACHE_MIN_HIT_RATE_FOR_MEM_TABLE) + { + DBUG_PRINT("info", ("hit rate is not so good to keep the cache")); + free_tmp_table(table_thd, cache_table); + cache_table= NULL; + DBUG_RETURN(FALSE); + } + else if (hit_rate < EXPCACHE_MIN_HIT_RATE_FOR_DISK_TABLE) + { + DBUG_PRINT("info", ("hit rate is not so good to go to disk")); + if (cache_table->file->ha_delete_all_rows() || + cache_table->file->ha_write_tmp_row(cache_table->record[0])) + goto err; + } + else + { + if (create_internal_tmp_table_from_heap(table_thd, cache_table, + cache_table_param.start_recinfo, + &cache_table_param.recinfo, + error, 1)) + goto err; + } + } } cache_table->status= 0; /* cache_table->record contains an existed record */ ref.has_record= TRUE; /* the same as above */ diff --git a/sql/sql_expression_cache.h b/sql/sql_expression_cache.h index f1d141abbd1..f02c3f8caca 100644 --- a/sql/sql_expression_cache.h +++ b/sql/sql_expression_cache.h @@ -85,6 +85,8 @@ private: List &items; /* Value Item example */ Item *val; + /* hit/miss counters */ + uint hit, miss; /* Set on if the object has been succesfully initialized with init() */ bool inited; }; -- cgit v1.2.1