Commit a8dc3236 authored by Kristofer Pettersson's avatar Kristofer Pettersson

Bug#37416 When SQL_NO_CACHE is used, MySQL still lookup into the query cache

      
The query cache module did not check for the SQL_NO_CACHE keyword before
attempting to query the hash lookup table. This had a small performance impact.
      
By introducing a check on the query string before obtaining the hash mutex
we can gain some performance if the SQL_NO_CACHE directive is used often.
parent e59a0361
...@@ -363,6 +363,43 @@ TYPELIB query_cache_type_typelib= ...@@ -363,6 +363,43 @@ TYPELIB query_cache_type_typelib=
array_elements(query_cache_type_names)-1,"", query_cache_type_names, NULL array_elements(query_cache_type_names)-1,"", query_cache_type_names, NULL
}; };
/**
Helper function for determine if a SELECT statement has a SQL_NO_CACHE
directive.
@param sql A pointer to the first white space character after SELECT
@return
@retval TRUE The character string contains SQL_NO_CACHE
@retval FALSE No directive found.
*/
static bool has_no_cache_directive(char *sql)
{
int i=0;
while (sql[i] == ' ')
++i;
if (my_toupper(system_charset_info, sql[i]) == 'S' &&
my_toupper(system_charset_info, sql[i+1]) == 'Q' &&
my_toupper(system_charset_info, sql[i+2]) == 'L' &&
my_toupper(system_charset_info, sql[i+3]) == '_' &&
my_toupper(system_charset_info, sql[i+4]) == 'N' &&
my_toupper(system_charset_info, sql[i+5]) == 'O' &&
my_toupper(system_charset_info, sql[i+6]) == '_' &&
my_toupper(system_charset_info, sql[i+7]) == 'C' &&
my_toupper(system_charset_info, sql[i+8]) == 'A' &&
my_toupper(system_charset_info, sql[i+9]) == 'C' &&
my_toupper(system_charset_info, sql[i+10]) == 'H' &&
my_toupper(system_charset_info, sql[i+11]) == 'E' &&
my_toupper(system_charset_info, sql[i+12]) == ' ')
return TRUE;
return FALSE;
}
/***************************************************************************** /*****************************************************************************
Query_cache_block_table method(s) Query_cache_block_table method(s)
*****************************************************************************/ *****************************************************************************/
...@@ -1085,6 +1122,16 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) ...@@ -1085,6 +1122,16 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
DBUG_PRINT("qcache", ("The statement is not a SELECT; Not cached")); DBUG_PRINT("qcache", ("The statement is not a SELECT; Not cached"));
goto err; goto err;
} }
if (query_length > 20 && has_no_cache_directive(&sql[i+6]))
{
/*
We do not increase 'refused' statistics here since it will be done
later when the query is parsed.
*/
DBUG_PRINT("qcache", ("The statement has a SQL_NO_CACHE directive"));
goto err;
}
} }
#ifdef __WIN__ #ifdef __WIN__
......
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