最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

對于mysql的query_cache認識的誤區(qū)

 更新時間:2012年03月30日 00:44:14   作者:  
一直以來,對于mysql的query_cache,在網(wǎng)上就流行著這樣的說法,對于mysql的query_cache鍵值就是mysql的query,所以,如果在query中有任何的不同,包括多了個空格,都會導(dǎo)致mysql認為是不同的查詢
其實,這一種說法是不完全正確的。首先第一點,mysql的query_cache的鍵值并不是簡單的query,而是query加databasename加flag。這個從源碼中就可以看出。在這里不做重點描述,后續(xù)可以針對于這一點再具體分析。重要的是第二點,是不是加了空格,mysql就認為是不同的查詢呢?實際上這個是要分情況而言的,要看這個空格加在哪。 如果空格是加在query之前,比如是在query的起始處加了空格,這樣是絲毫不影響query cache的結(jié)果的,mysql認為這是一條query, 而如果空格是在query中,那會影響query cache的結(jié)果,mysql會認為是不同的query。

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

首先,我們看一下mysql query_cache的狀態(tài):

image

首先,我們可以確認,mysql的query_cache功能是打開的。

其次,我們看一下狀態(tài):

image

因為這個db是新的db,所以hits,inset都為0,現(xiàn)在我們執(zhí)行一條select語句:

狀態(tài)變?yōu)椋?/P>

image

可以看到,執(zhí)行一條select后,現(xiàn)在的qcache狀態(tài)為,insert+1,這樣我們就可以推斷出,現(xiàn)在剛才那條select語句已經(jīng)加入了qcache中。那我們現(xiàn)在再將剛才那條sql前面加上空格,看看會怎樣呢?

image

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

按照網(wǎng)上的理論,這條sql應(yīng)該會作為另一個鍵而插入另一個cache,不會復(fù)用先前的cache,但結(jié)果呢?

image

我們可以看到,hits變?yōu)榱?,而inserts根本沒變,這就說明了,這條在前面加了空格的query命中了沒有空格的query的結(jié)果集。從這,我們就可以得出結(jié)論,網(wǎng)上先前流傳的說法,是不嚴謹?shù)摹?/P>

那究竟是怎么回事呢?到底應(yīng)該如何呢?為什么前面有空格的會命中了沒有空格的query的結(jié)果集。其實,這些我們可以通過源碼獲得答案。

翻看下mysql的源碼,我這翻看的是5.1的,在send_result_to_client(這個函數(shù)既是mysql調(diào)用query_cache的函數(shù))這個函數(shù)里面有這樣一段,這段代碼,、

復(fù)制代碼 代碼如下:

/*
Test if the query is a SELECT
(pre-space is removed in dispatch_command).

First '/' looks like comment before command it is not
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,也就是說,在語句開始之前的多余的空格已經(jīng)被處理過了,在dispache_command這個函數(shù)中去掉了。

我們看下dispache_command這個方法,在這個方法里有這樣一段:

復(fù)制代碼 代碼如下:

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;

在這里,會調(diào)用alloc_query方法,我們看下這個方法的內(nèi)容:
復(fù)制代碼 代碼如下:

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掉。
看到這里,我們基本已經(jīng)明了了,mysql會對輸入的query進行預(yù)處理,將空格等東西給處理掉,所以不會開頭的空格不會影響到query_cache,因為對mysql來說,就是一條query。

相關(guān)文章

  • MySQL時區(qū)差8小時的多種問題解決方法

    MySQL時區(qū)差8小時的多種問題解決方法

    mybatis將本地的數(shù)據(jù)傳入到mysql數(shù)據(jù)庫服務(wù)器的時候,服務(wù)器會對數(shù)據(jù)進行檢測,會把date類型的數(shù)據(jù)自動轉(zhuǎn)換為mysql服務(wù)器所對應(yīng)的時區(qū),即0時區(qū),所以會相差8小時,本文給大家介紹了MySQL時區(qū)差8小時的問題解決方法,需要的朋友可以參考下
    2024-01-01
  • Mysql中@和@@符號的詳細使用指南

    Mysql中@和@@符號的詳細使用指南

    最近工作遇到了一個問題,給自己做個記錄,下面這篇文章主要給大家介紹了關(guān)于Mysql中@和@@符號的詳細使用的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-06-06
  • mysql連接過多和死掉以及拒絕服務(wù)的解決方法

    mysql連接過多和死掉以及拒絕服務(wù)的解決方法

    mysql連接過多和死掉以及拒絕服務(wù)的解決方法...
    2007-12-12
  • Linux下安裝mysql-5.6.12-linux-glibc2.5-x86_64.tar.gz

    Linux下安裝mysql-5.6.12-linux-glibc2.5-x86_64.tar.gz

    這篇文章主要介紹了Linux下安裝mysql-5.6.12-linux-glibc2.5-x86_64.tar.gz的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-09-09
  • MYSQL數(shù)據(jù)庫管理之權(quán)限管理解讀

    MYSQL數(shù)據(jù)庫管理之權(quán)限管理解讀

    這篇文章主要介紹了MYSQL數(shù)據(jù)庫管理之權(quán)限管理解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Mysql基礎(chǔ)知識點匯總

    Mysql基礎(chǔ)知識點匯總

    本文給大家匯總介紹了mysql的23個基礎(chǔ)的知識點,這些都是學(xué)習(xí)mysql的必備知識,小伙伴們可以參考下。
    2015-09-09
  • mysql中怎樣使用合適的字段和字段長度

    mysql中怎樣使用合適的字段和字段長度

    這篇文章主要介紹了mysql中怎樣使用合適的字段和字段長度問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • 10個mysql中select語句的簡單用法

    10個mysql中select語句的簡單用法

    本篇文章主要講述的是MySQL SELECT句法的簡單分析,我們大家都知道MySQL數(shù)據(jù)庫是我們大家經(jīng)常使用的數(shù)據(jù)庫,其相關(guān)的應(yīng)用也是備受關(guān)注的,那么以下的文章主要是對MySQL SELECT句法的簡單分析。
    2014-08-08
  • sql語句中l(wèi)ike的用法詳細解析

    sql語句中l(wèi)ike的用法詳細解析

    以下是對sql語句中l(wèi)ike的用法進行了詳細的分析介紹,需要的朋友可以過來參考下
    2013-08-08
  • mysql復(fù)制表的幾種常用方式

    mysql復(fù)制表的幾種常用方式

    這篇文章主要給大家介紹了關(guān)于MySQL中復(fù)制表的幾種常用方式,我們在對一張表進行操作,但是怕誤刪數(shù)據(jù),所以在同一個數(shù)據(jù)庫中建一個表結(jié)構(gòu)一樣,表數(shù)據(jù)也一樣的表,以作備份,需要的朋友可以參考下
    2023-08-08

最新評論

天峨县| 金沙县| 南部县| 双牌县| 台安县| 五寨县| 陕西省| 北京市| 玉溪市| 曲周县| 偃师市| 林周县| 灌南县| 施秉县| 金乡县| 庆阳市| 读书| 鹤庆县| 汶川县| 扎鲁特旗| 绵竹市| 天水市| 渑池县| 焉耆| 泰州市| 安福县| 长治县| 太康县| 钟祥市| 环江| 明水县| 柳江县| 东山县| 红桥区| 赤壁市| 武汉市| 西平县| 通海县| 安新县| 桦川县| 绥德县|