PHP的中使用非緩沖模式查詢數(shù)據(jù)庫的方法
最近在開發(fā)一個(gè)PHP程序時(shí)遇到了下面的錯(cuò)誤:
PHP Fatal error: Allowed memory size of 268 435 456 bytes exhausted
錯(cuò)誤信息顯示允許的最大內(nèi)存已經(jīng)耗盡。遇到這樣的錯(cuò)誤起初讓我很詫異,但轉(zhuǎn)眼一想,也不奇怪,因?yàn)槲艺陂_發(fā)的這個(gè)程序是要用一個(gè)foreach循環(huán)語句在一個(gè)有4萬條記錄的表里全表搜索具有特定特征的數(shù)據(jù),也就是說,一次要把4萬條數(shù)據(jù)取出,然后逐條檢查每天數(shù)據(jù)??上攵?萬條數(shù)據(jù)全部加載到內(nèi)存中,內(nèi)存不爆才怪。
畢竟編程這么多年,我隱約記得PHP里提供有非一次全部加載數(shù)據(jù)的API,是像處理流媒體那樣,隨用隨取隨丟、數(shù)據(jù)并不會積累在內(nèi)存的查詢方法。經(jīng)過簡單的搜索,果然在官方網(wǎng)站上找到的正確的用法。緩沖查詢和非緩沖查詢(Buffered and Unbuffered queries)。PHP的查詢?nèi)笔∧J绞蔷彌_模式。也就是說,查詢數(shù)據(jù)結(jié)果會一次全部提取到內(nèi)存里供PHP程序處理。這樣給了PHP程序額外的功能,比如說,計(jì)算行數(shù),將指針指向某一行等。更重要的是程序可以對數(shù)據(jù)集反復(fù)進(jìn)行二次查詢和過濾等操作。但這種緩沖查詢模式的缺陷就是消耗內(nèi)存。
另外一種PHP查詢模式是非緩沖查詢,數(shù)據(jù)庫服務(wù)器會一條一條的返回?cái)?shù)據(jù),而不是一次全部返回,這樣的結(jié)果就是PHP程序消耗較少的內(nèi)存,但卻增加了數(shù)據(jù)庫服務(wù)器的壓力,因?yàn)閿?shù)據(jù)庫會一直等待PHP來取數(shù)據(jù),一直到數(shù)據(jù)全部取完。
非緩沖查詢方法一: mysqli
<?php $mysqli = new mysqli("localhost", "my_user", "my_password", "world"); $uresult = $mysqli->query("SELECT Name FROM City", MYSQLI_USE_RESULT); if ($uresult) { while ($row = $uresult->fetch_assoc()) { echo $row['Name'] . PHP_EOL; } } $uresult->close();
非緩沖查詢方法二: pdo_mysql
<?php $pdo = new PDO("mysql:host=localhost;dbname=world", 'my_user', 'my_pass'); $pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false); $uresult = $pdo->query("SELECT Name FROM City"); if ($uresult) { while ($row = $uresult->fetch(PDO::FETCH_ASSOC)) { echo $row['Name'] . PHP_EOL; } }
非緩沖查詢方法三: mysql
<?php $conn = mysql_connect("localhost", "my_user", "my_pass"); $db = mysql_select_db("world"); $uresult = mysql_unbuffered_query("SELECT Name FROM City"); if ($uresult) { while ($row = mysql_fetch_assoc($uresult)) { echo $row['Name'] . PHP_EOL; } }
注:引之 http://www.webhek.com/php-buffered-and-unbuffered-queries
手冊資料 http://php.net/manual/zh/mysqlinfo.concepts.buffering.php
- PHP中數(shù)據(jù)庫單例模式的實(shí)現(xiàn)代碼分享
- php設(shè)計(jì)模式 DAO(數(shù)據(jù)訪問對象模式)
- 淺析php設(shè)計(jì)模式之?dāng)?shù)據(jù)對象映射模式
- PHP基于單例模式實(shí)現(xiàn)的數(shù)據(jù)庫操作基類
- PHP實(shí)現(xiàn)的數(shù)據(jù)對象映射模式詳解
- PHP單例模式應(yīng)用示例【多次連接數(shù)據(jù)庫只實(shí)例化一次】
- PHP單例模式數(shù)據(jù)庫連接類與頁面靜態(tài)化實(shí)現(xiàn)方法
- PHP數(shù)據(jù)對象映射模式實(shí)例分析
- PHP設(shè)計(jì)模式之?dāng)?shù)據(jù)訪問對象模式(DAO)原理與用法實(shí)例分析
- PHP數(shù)據(jù)源架構(gòu)模式之表入口模式實(shí)例分析
相關(guān)文章
發(fā)款php蜘蛛統(tǒng)計(jì)插件只要有mysql就可用
有時(shí)候我們?yōu)榱丝匆幌轮┲肱佬械那闆r,不得不對日志進(jìn)行大量的分析,由此想做一款插件可以記錄蜘蛛的情況。在第一次做的時(shí)候,只是記錄下蜘蛛的爬行次數(shù),不大好分析。2010-10-10php銀聯(lián)網(wǎng)頁支付實(shí)現(xiàn)方法
這篇文章主要介紹了php銀聯(lián)網(wǎng)頁支付實(shí)現(xiàn)方法,實(shí)例分析了php操作銀聯(lián)網(wǎng)支付接口的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03學(xué)習(xí)php設(shè)計(jì)模式 php實(shí)現(xiàn)適配器模式
這篇文章主要介紹了php設(shè)計(jì)模式中的適配器模式,使用php實(shí)現(xiàn)適配器模式,感興趣的小伙伴們可以參考一下2015-12-12php中的路徑問題與set_include_path使用介紹
這篇文章主要介紹了php中的路徑問題與set_include_path,需要的朋友可以參考下2014-02-02解析:php調(diào)用MsSQL存儲過程使用內(nèi)置RETVAL獲取過程中的return值
本篇文章是對php調(diào)用MsSQL存儲過程使用內(nèi)置RETVAL獲取過程中的return值的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-07-07Uncaught exception com_exception with message Failed to crea
Fatal error: Uncaught exception 'com_exception' with message 'Failed to create COM object `InternetExplorer.Application': 拒絕訪問2012-01-01