程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> 其他數據庫知識 >> MSSQL >> SQL server 隨機數函數

SQL server 隨機數函數

編輯:MSSQL

SQL server 隨機數函數。本站提示廣大學習愛好者:(SQL server 隨機數函數)文章只能為提供參考,不一定能成為您想要的結果。以下是SQL server 隨機數函數正文


其實,這一種說法是不完整准確的。起首第一點,mysql的query_cache的鍵值其實不是簡略的query,而是query加databasename加flag。這個從源碼中便可以看出。在這裡不做重點描寫,後續可以針關於這一點再詳細剖析。主要的是第二點,是否是加了空格,mysql就以為是分歧的查詢呢?現實上這個是要分情形而言的,要看這個空格加在哪。 假如空格是加在query之前,好比是在query的肇端處加了空格,如許是涓滴不影響query cache的成果的,mysql以為這是一條query, 而假如空格是在query中,那會影響query cache的成果,mysql會以為是分歧的query。

上面我們經由過程試驗及源碼詳細剖析。起首,我們先實驗一下:

起首,我們看一下mysql query_cache的狀況:

image

起首,我們可以確認,mysql的query_cache功效是翻開的。

其次,我們看一下狀況:

image

由於這個db是新的db,所以hits,inset都為0,如今我們履行一條select語句:

狀況變成:

image

可以看到,履行一條select後,如今的qcache狀況為,insert+1,如許我們便可以揣摸出,如今適才那條select語句曾經參加了qcache中。那我們如今再將適才那條sql後面加上空格,看看會如何呢?

image

請留意,這條sql,比適才那條sql後面多了一個空格。

依照網上的實際,這條sql應當會作為另外一個鍵而拔出另外一個cache,不會復用先前的cache,但成果呢?

image

我們可以看到,hits變成了1,而inserts基本沒變,這就解釋了,這條在後面加了空格的query射中了沒有空格的query的成果集。從這,我們便可以得出結論,網上先前傳播的說法,是不嚴謹的。

那畢竟是怎樣回事呢?究竟應當若何呢?為何後面有空格的會射中了沒有空格的query的成果集。其實,這些我們可以經由過程源碼取得謎底。

翻看下mysql的源碼,我這翻看的是5.1的,在send_result_to_client(這個函數既是mysql挪用query_cache的函數)這個函數外面有如許一段,這段代碼,、

/*
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,也就是說,在語句開端之前的過剩的空格曾經被處置過了,在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。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved