下面我們通過實驗及源碼具體分析。首先,我們先試驗一下:
首先,我們看一下mysql query_cache的狀態:
因為這個db是新的db,所以hits,inset都為0,現在我們執行一條select語句:
狀態變為:
請注意,這條sql,比剛才那條sql前面多了一個空格。
按照網上的理論,這條sql應該會作為另一個鍵而插入另一個cache,不會復用先前的cache,但結果呢?
frequently appeared in real life, consequently we can 
check all such queries, too. 
*/ 
if ((my_toupper(system_charset_info, sql[i]) != 'S' || 
my_toupper(system_charset_info, sql[i + 1]) != 'E' || 
my_toupper(system_charset_info, sql[i + 2]) != 'L') && 
sql[i] != '/') 
{ 
DBUG_PRINT("qcache", ("The statement is not a SELECT; Not cached")); 
goto err; 
} 
我們看下dispache_command這個方法,在這個方法里有這樣一段:
復制代碼 代碼如下:
 
if (alloc_query(thd, packet, packet_length)) 
break; // fatal error is set 
char *packet_end= thd->query() + thd->query_length(); 
/* 'b' stands for 'buffer' parameter', special for 'my_snprintf' */ 
const char* end_of_stmt= NULL; 
復制代碼 代碼如下:
 
bool alloc_query(THD *thd, const char *packet, uint packet_length) 
{ 
char *query; 
/* Remove garbage at start and end of query */ 
while (packet_length > 0 && my_isspace(thd->charset(), packet[0])) 
{ 
packet++; 
packet_length--; 
} 
const char *pos= packet + packet_length; // Point at end null 
while (packet_length > 0 && 
(pos[-1] == ';' || my_isspace(thd->charset() ,pos[-1]))) 
{ 
pos--; 
packet_length--; 
} 
/* We must allocate some extra memory for query cache 
The query buffer layout is: 
buffer :== 
<statement> The input statement(s) 
'/0' Terminating null char (1 byte) 
<length> Length of following current database name (size_t) 
<db_name> Name of current database 
<flags> Flags struct 
*/ 
if (! (query= (char*) thd->memdup_w_gap(packet, 
packet_length, 
1 + sizeof(size_t) + thd->db_length + 
QUERY_CACHE_FLAGS_SIZE))) 
return TRUE; 
query[packet_length]= '/0'; 
/* 
Space to hold the name of the current database is allocated. We 
also store this length, in case current database is changed during 
execution. We might need to reallocate the 'query' buffer 
*/ 
char *len_pos = (query + packet_length + 1); 
memcpy(len_pos, (char *) &thd->db_length, sizeof(size_t)); 
thd->set_query(query, packet_length); 
/* Reclaim some memory */ 
thd->packet.shrink(thd->variables.net_buffer_length); 
thd->convert_buffer.shrink(thd->variables.net_buffer_length); 
return FALSE; 
} 
新聞熱點
疑難解答