国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > MySQL > 正文

對于mysql的query_cache認識的誤區

2024-07-24 13:02:29
字體:
來源:轉載
供稿:網友
其實,這一種說法是不完全正確的。首先第一點,mysql的query_cache的鍵值并不是簡單的query,而是query加databasename加flag。這個從源碼中就可以看出。在這里不做重點描述,后續可以針對于這一點再具體分析。重要的是第二點,是不是加了空格,mysql就認為是不同的查詢呢?實際上這個是要分情況而言的,要看這個空格加在哪。 如果空格是加在query之前,比如是在query的起始處加了空格,這樣是絲毫不影響query cache的結果的,mysql認為這是一條query, 而如果空格是在query中,那會影響query cache的結果,mysql會認為是不同的query。

下面我們通過實驗及源碼具體分析。首先,我們先試驗一下:

首先,我們看一下mysql query_cache的狀態:

對于mysql的query_cache認識的誤區

因為這個db是新的db,所以hits,inset都為0,現在我們執行一條select語句:

狀態變為:

對于mysql的query_cache認識的誤區

請注意,這條sql,比剛才那條sql前面多了一個空格。

按照網上的理論,這條sql應該會作為另一個鍵而插入另一個cache,不會復用先前的cache,但結果呢?

對于mysql的query_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;
}


是在檢驗語句是否為select語句,重點是上面那段注釋。特別是括弧中的,pre-space is removed in dispatch_command,也就是說,在語句開始之前的多余的空格已經被處理過了,在dispache_command這個函數中去掉了。

我們看下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;


在這里,會調用alloc_query方法,我們看下這個方法的內容:

復制代碼 代碼如下:


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;
}


這個方法在一開始就會對query進行處理(代碼第4行),將開頭和末尾的garbage remove掉。
看到這里,我們基本已經明了了,mysql會對輸入的query進行預處理,將空格等東西給處理掉,所以不會開頭的空格不會影響到query_cache,因為對mysql來說,就是一條query。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 赫章县| 高陵县| 龙海市| 金寨县| 孝义市| 双桥区| 金堂县| 京山县| 巨鹿县| 乳山市| 丰台区| 高要市| 油尖旺区| 天津市| 巫山县| 连江县| 唐河县| 长葛市| 沾益县| 昂仁县| 焦作市| 渭源县| 鹿邑县| 商城县| 北流市| 横山县| 淄博市| 景洪市| 长顺县| 本溪市| 阳曲县| 宁化县| 剑河县| 三门峡市| 朝阳县| 黄梅县| 宜章县| 合江县| 梅州市| 阳东县| 汨罗市|