#At file:///home/thek/Development/cpp/mysqlbzr/mysql-5.0-bug37416/
2693 Kristofer Pettersson 2008-10-08
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.
modified:
sql/sql_cache.cc
=== modified file 'sql/sql_cache.cc'
--- a/sql/sql_cache.cc 2008-07-24 14:14:34 +0000
+++ b/sql/sql_cache.cc 2008-10-08 09:28:40 +0000
@@ -357,6 +357,8 @@ TODO list:
#define DUMP(C)
#endif
+bool has_no_cache_directive(char *sql);
+
const char *query_cache_type_names[]= { "OFF", "ON", "DEMAND",NullS };
TYPELIB query_cache_type_typelib=
{
@@ -1085,6 +1087,16 @@ Query_cache::send_result_to_client(THD *
DBUG_PRINT("qcache", ("The statement is not a SELECT; Not cached"));
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__
@@ -4289,4 +4301,34 @@ err2:
#endif /* DBUG_OFF */
+
+/**
+ 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.
+*/
+
+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]) == '_')
+ return TRUE;
+
+ return FALSE;
+}
+
+
#endif /*HAVE_QUERY_CACHE*/