首頁  >  文章  >  資料庫  >  如何解決PHP使用mysql_query查詢超大結果集超記憶體問題

如何解決PHP使用mysql_query查詢超大結果集超記憶體問題

黄舟
黄舟原創
2016-12-13 17:56:391008瀏覽

mysql的查詢還提供了另外一種查詢方式,函數名為mysql_unbuffered_query,這個函數採用的是查出結果後立即操作結果集,並不會把結果集緩存到內存中,這樣就避免了超出內存的情況發生。但是使用這個方法的代價就是不能再查詢的時候使用取得總行之類的方法,因為這種方法就是便查詢邊回傳結果。同時在使用該方法的時候不能在同一資料庫連結上執行其他的操作,想要執行其他操作的時候必須先終止目前操作,釋放所有未快取的sql查詢所產生的結果行,或是重新實例化一個資料庫連接,使用新連結進行其他操作。

以下是使用快取和不使用快取的對比(所查詢的表中有1000多萬行資料):

function selecttest()
{
try {
$pdo = new PDO("mysql:host=localhost;dbname=test", 'root', '123456');
// 不使用缓存结果集方式
// $pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
$sth = $pdo->prepare('select * from test');
$sth->execute();
echo '最初占用内存大小:' . memory_get_usage() . "\n";
$i = 0;
while ($result = $sth->fetch(PDO::FETCH_ASSOC)) {
$i += 1;
if ($i > 10) {
break;
}
sleep(1);
print_r($result);
echo '占用内存大小:' . memory_get_usage() . "\n";
}
} catch (Exception $e) {
echo $e->getMessage();
}
}

上面使用到的是快取所有結果集的方式,運行該函數時將會報超記憶體的錯誤,如下圖所示:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 204800000 bytes) in E:ProgramDevelopmentRuntest testopmentRundronment.


0.0005 135392 1. { main}() E:ProgramDevelopmentRuntimeEnvironmentxampphtdocstesttest.php:0

0.0005 135568 2. test->selecttest() E:ProgramDevelopmentRuntimeEnvironmentxampphtdocsstesttest.S. opmentRuntimeEnvironmentxampphtdocstesttest.php:57


在執行$sth->execute();時超出記憶體限制;

將// $pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);這行的註解去掉後將使用不緩存結果集的方式,運行緩存結果集的方式,運行函數將輸出以下內容:

最初佔用記憶體大小:144808

Array
(
[id] => 1
[a] => v
[b] => w
[c] => i
)

佔用記憶體大小:145544

Array
(
[id] => 2
[a] => b
[b] => l
[c] => q
)

佔用記憶體大小:145544

Array
(
[id] => 3
[a] => m
[b] => p
[c] => h
)

佔用記憶體大小:145536

可以看到,使用不緩存結果集的方式取得一行結果所佔用的記憶體是極少的。這樣就結局了超出記憶體限制的問題。

感謝您的閱讀,希望可以為您帶來幫助,想要獲取更多的相關內容請關注PHP中文網(www.php.cn)!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn