如何解決PHP使用mysql_query查詢超大結果集超內存問題

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:ProgramDevelopmentRuntimeEnvironmentxampphtdocstesttest.php on line 57

Call Stack:

立即學習PHP免費學習筆記(深入)”;

0.0005 135392 1. {main}() E:ProgramDevelopmentRuntimeEnvironmentxampphtdocstesttest.php:0
0.0005 135568 2. test->selecttest() E:ProgramDevelopmentRuntimeEnvironmentxampphtdocstesttest.php:86
0.0055 142528 3. PDOStatement->execute() E:ProgramDevelopmentRuntimeEnvironmentxampphtdocstesttest.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

Array  (  [id]?=>?4  [a]?=>?j  [b]?=>?i  [c]?=>?b  )

占用內存大小:145536

Array  (  [id]?=>?5  [a]?=>?q  [b]?=>?g  [c]?=>?g  )

占用內存大小:145536

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

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

? 版權聲明
THE END
喜歡就支持一下吧
點贊14 分享