《PHP應(yīng)用:對比PHP對MySQL的緩沖查詢和無緩沖查詢》要點(diǎn):
本文介紹了PHP應(yīng)用:對比PHP對MySQL的緩沖查詢和無緩沖查詢,希望對您有用。如果有疑問,可以聯(lián)系我們。
PHP學(xué)習(xí)關(guān)于緩沖查詢和無緩沖查詢
MySQL的客戶端有兩種類型的查詢:
緩沖查詢:將接收查詢的結(jié)果并把他們存儲在客戶端的緩存中,而且接下來獲取行記錄的請求僅僅從本地內(nèi)獲取.
(1)優(yōu)點(diǎn):可以在結(jié)果集中自由地移動“當(dāng)前行”的指針,這樣很容易找到,因為結(jié)果是存在客戶端的.
(2)缺點(diǎn):需要額外的內(nèi)存來存儲這些結(jié)果集,而且需要大量的內(nèi)存,另外,php中用來運(yùn)行查詢的函數(shù)會一直到所有的結(jié)果都接收才會返回值.
PHP學(xué)習(xí)無緩沖查詢:會限制你通過嚴(yán)格的順序訪問查詢結(jié)果.但他不需要額外的內(nèi)存來存儲整個結(jié)果集.你可以在MySQL服務(wù)器開始返回值的時候就開始獲取而處理或顯示數(shù)據(jù)行.當(dāng)使用無緩沖結(jié)果集時,必須使用mysql_fetch_row函數(shù)獲取所以的數(shù)據(jù)行,或者在給服務(wù)器發(fā)送其他任何命令前用mysql_free_result函數(shù)關(guān)閉結(jié)果集.
PHP學(xué)習(xí)哪種類型的查詢好?最好的根據(jù)是具體情況而定,無緩沖查詢在結(jié)果集巨大的時為你節(jié)省大量的臨時內(nèi)存,而且查詢不需要排序時,php在MySQL數(shù)據(jù)庫實際上還在處理時就可以獲得第一個數(shù)據(jù)行.
緩存查詢便于尋找,它可以提供一個全面的尋找加速.因為每一個單獨(dú)的查詢的都會快讀結(jié)束,mysql快速的獲取結(jié)果集并存放在內(nèi)存中,而不是在處理PHP代碼時保持查詢?yōu)榭捎玫?
另外一個無緩沖查詢的限制是在所有的數(shù)據(jù)行都被讀取或者結(jié)果集用mysqli_free_result釋放之前,你將無法向服務(wù)器發(fā)送任何命令.
PHP學(xué)習(xí)
PHP+MySQL緩沖查詢和無緩沖查詢
PHP MySQL查詢(mysqli,pdo_mysql)默認(rèn)使用緩沖模式.
也就是說查詢結(jié)果將一次性從MySQL傳輸?shù)絇HP進(jìn)程內(nèi)存中,
這時可以統(tǒng)計結(jié)果集的行數(shù),以及移動結(jié)果集指針.
緩沖模式下,如果結(jié)果集很大,那么PHP進(jìn)程也會占用大量的內(nèi)存,
直到結(jié)果集被unset或者free.
PHP學(xué)習(xí)store_result用于緩沖模式,所有結(jié)果一次性存儲到PHP進(jìn)程中:
PHP學(xué)習(xí)
mysqli::query MYSQLI_STORE_RESULT
mysqli::store_result
mysqli_stmt::store_result
PHP學(xué)習(xí)如果PHP的MySQL數(shù)據(jù)庫驅(qū)動底層用的是libmysqlclient,那么memory_limit不能統(tǒng)計到結(jié)果集占用的內(nèi)存,
除非結(jié)果集已經(jīng)賦值給PHP變量,如果底層使用mysqlnd作為驅(qū)動時則可以統(tǒng)計到(PHP從5.4開始底層默認(rèn)使用mysqlnd).
無緩沖模式下執(zhí)行的查詢將會返回一個resource資源引用,位于MySQL的查詢結(jié)果等待PHP獲取.
無緩沖模式下,PHP進(jìn)程占用的內(nèi)存很少,但會增大MySQL服務(wù)器的負(fù)載.
在PHP取回所有結(jié)果前,在當(dāng)前數(shù)據(jù)庫連接下不能發(fā)送其他的查詢請求.
PHP學(xué)習(xí)use_result表示無緩沖查詢:
PHP學(xué)習(xí)
mysqli::query MYSQLI_USE_RESULT
mysqli::use_result
PHP學(xué)習(xí)總結(jié):
當(dāng)結(jié)果集不大時,或者需要在讀取所有行前獲取結(jié)果集行數(shù)時,使用緩沖查詢(默認(rèn)).
當(dāng)結(jié)果集很大時,使用無緩沖查詢,避免PHP進(jìn)程占用大量的內(nèi)存.
PHP學(xué)習(xí)
$rs = $mysqli->query("SELECT * FROM City", MYSQLI_USE_RESULT);
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
$rs = $pdo->query("SELECT * FROM City");
PHP學(xué)習(xí)默認(rèn)情況下,mysqli_stmt的SELECT查詢結(jié)果將留在MySQL服務(wù)器上,等待fetch方法把記錄逐條取回到PHP程序中,這樣做會降低性能,但能節(jié)省內(nèi)存.
如果需要對所有記錄進(jìn)行處理,可以調(diào)用mysqli_stmt::store_result,把所有結(jié)果一次性全部傳回到PHP程序中,
這樣做更高效,能減輕MySQL服務(wù)器的負(fù)擔(dān),雖然內(nèi)存占用會多一些.
如果獲取SELECT語句查找到了多少條記錄,可以用 mysqli_stmt::$num_rows 獲取.
這個屬性只有在提前執(zhí)行過 mysqli_stmt::store_result 方法,將全部查詢結(jié)果傳回到PHP程序中的情況下才可以使用.
對比 mysqli_result::$num_rows 則不沒有這個限制.
用 mysqli_stmt::free_result 關(guān)閉 mysqli_stmt::store_result:
PHP學(xué)習(xí)
$stmt->store_result();
echo $stmt->num_rows;
$stmt->free_result();
PHP學(xué)習(xí)
$result = $stmt->get_result();
$results = $result->fetch_all(MYSQLI_ASSOC);
PHP學(xué)習(xí)
mysqli::query//執(zhí)行SQL,成功返回mysqli_result(SELECT,SHOW,DESCRIBE操作)對象或TRUE(其他操作),失敗返回FALSE.用mysqli::close關(guān)閉.
mysqli::prepare//預(yù)處理SQL,成功返回statement對象,失敗返回FALSE.
mysqli_stmt::execute//執(zhí)行SQL.用mysqli_stmt::close關(guān)閉.
mysqli_stmt::store_result//取回全部查詢結(jié)果(SELECT,SHOW,DESCRIBE,EXPLAIN)到PHP,可選.用mysqli_stmt::free_result關(guān)閉.
mysqli_stmt::bind_result//把prepare和execute產(chǎn)生的結(jié)構(gòu)綁定結(jié)果到變量,然后在mysqli_stmt::fetch中把這些變量輸出或賦值.
mysqli_stmt::fetch//每次返回結(jié)果集的一條,賦值給mysqli_stmt::bind_result綁定的變量.
mysqli_stmt::get_result//獲得結(jié)果對象,然后調(diào)用mysqli_result::fetch_all就能返回結(jié)果集數(shù)組.mysqlnd下可用.
mysqli_result::fetch_all//返回一個結(jié)果集數(shù)組(MYSQLI_NUM(默認(rèn)),MYSQLI_ASSOC,MYSQLI_BOTH),用mysqli_result::close關(guān)閉.mysqlnd下可用.
mysqli_result::fetch_array//每次返回結(jié)果集的一條,包含一個一維的數(shù)字?jǐn)?shù)組和關(guān)聯(lián)數(shù)組.
mysqli_result::fetch_assoc//每次返回結(jié)果集的一條,即一個一維的關(guān)聯(lián)數(shù)組.
mysqli_result::fetch_row//每次返回結(jié)果集的一條,即一個一維的數(shù)字?jǐn)?shù)組.
轉(zhuǎn)載請注明本頁網(wǎng)址:
http://www.fzlkiss.com/jiaocheng/5905.html