PHP+MySQL緩沖查詢和無緩沖查詢
http://php.net/manual/zh/mysqlinfo.concepts.buffering.php
http://php.net/manual/zh/mysqli.query.php
PHP MySQL查詢(mysqli,pdo_mysql)默認使用緩沖模式.
也就是說查詢結果將一次性從MySQL傳輸到PHP進程內存中,
這時可以統計結果集的行數,以及移動結果集指針.
緩沖模式下,如果結果集很大,那么PHP進程也會占用大量的內存,
直到結果集被unset或者free.
store_result用于緩沖模式,所有結果一次性存儲到PHP進程中:
mysqli::query MYSQLI_STORE_RESULT
mysqli::store_result
mysqli_stmt::store_result
如果PHP的MySQL數據庫驅動底層用的是libmysqlclient,那么memory_limit不能統計到結果集占用的內存,
除非結果集已經賦值給PHP變量,如果底層使用mysqlnd作為驅動時則可以統計到(PHP從5.4開始底層默認使用mysqlnd).
無緩沖模式下執行的查詢將會返回一個resource資源引用,位于MySQL的查詢結果等待PHP獲取.
無緩沖模式下,PHP進程占用的內存很少,但會增大MySQL服務器的負載.
在PHP取回所有結果前,在當前數據庫連接下不能發送其他的查詢請求.
use_result表示無緩沖查詢:
mysqli::query MYSQLI_USE_RESULT
mysqli::use_result
總結:
當結果集不大時,或者需要在讀取所有行前獲取結果集行數時,使用緩沖查詢(默認).
當結果集很大時,使用無緩沖查詢,避免PHP進程占用大量的內存.
$rs = $mysqli->query("SELECT FROM City", MYSQLI_USE_RESULT);
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
$rs = $pdo->query("SELECT FROM City");
默認情況下,mysqli_stmt的SELECT查詢結果將留在MySQL服務器上,等待fetch方法把記錄逐條取回到PHP程序中,這樣做會降低性能,但能節省內存.
如果需要對所有記錄進行處理,可以調用mysqli_stmt::store_result,把所有結果一次性全部傳回到PHP程序中,
這樣做更高效,能減輕MySQL服務器的負擔,雖然內存占用會多一些.
如果獲取SELECT語句查找到了多少條記錄,可以用 mysqli_stmt::$num_rows 獲取.
這個屬性只有在提前執行過 mysqli_stmt::store_result 方法,將全部查詢結果傳回到PHP程序中的情況下才可以使用.
對比 mysqli_result::$num_rows 則不沒有這個限制.
用 mysqli_stmt::free_result 關閉 mysqli_stmt::store_result:
$stmt->store_result();
echo $stmt->num_rows;
$stmt->free_result();
http://php.net/manual/zh/mysqli-stmt.fetch.php
mysqli_stmt::store_result能讓mysqli_stmt::fetch更高效,但也需要用mysqli_stmt::free_result顯式關閉.
可以用mysqli_stmt::get_result拿到結果集對象$result,然后mysqli_result::fetch_all拿到查詢數組$results:
$result = $stmt->get_result();
$results = $result->fetch_all(MYSQLI_ASSOC);
http://php.net/mysqli
mysqli::query 執行SQL,成功返回 mysqli_result(SELECT,SHOW,DESCRIBE操作)對象或TRUE(其他操作), 失敗返回FALSE.用 mysqli::close 關閉.
mysqli::prepare 預處理SQL,成功返回 statement 對象, 失敗返回 FALSE.
mysqli_stmt::execute 執行SQL.用 mysqli_stmt::close 關閉.
mysqli_stmt::store_result 取回全部查詢結果(SELECT,SHOW,DESCRIBE,EXPLAIN)到PHP,可選.用 mysqli_stmt::free_result 關閉.
mysqli_stmt::bind_result 把prepare和execute產生的結構綁定結果到變量,然后在 mysqli_stmt::fetch 中把這些變量輸出或賦值.
mysqli_stmt::fetch 每次返回結果集的一條,賦值給 mysqli_stmt::bind_result 綁定的變量.
mysqli_stmt::get_result 獲得結果對象,然后調用 mysqli_result::fetch_all 就能返回結果集數組.mysqlnd下可用.
mysqli_result::fetch_all 返回一個結果集數組(MYSQLI_NUM(默認),MYSQLI_ASSOC,MYSQLI_BOTH),用 mysqli_result::close 關閉.mysqlnd下可用.
mysqli_result::fetch_array 每次返回結果集的一條,包含一個一維的數字數組和關聯數組.
mysqli_result::fetch_assoc 每次返回結果集的一條,即一個一維的關聯數組.
mysqli_result::fetch_row 每次返回結果集的一條,即一個一維的數字數組.