国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

PHP+MySQL導出大量數據(Iterator yield)

codergarden / 2334人閱讀

摘要:開發中經常遇到這樣的場景產品汪我要在后臺做一個功能,可以導出自定義時間范圍的訂單信息。結果,第二天一上班產品汪過來就是拍桌子,我想把去年一整年的訂單都導出來,結果后臺直接就掛了開發小哥一查,原來是內存溢出了,一年下來的的訂單量足足有條。

開發中經常遇到這樣的場景

產品汪:我要在后臺做一個功能,可以導出自定義時間范圍的訂單信息。開發小哥二話不說,半天就把功能做完并上線了。結果,第二天一上班產品汪過來就是拍桌子:MD,我想把去年一整年的訂單都導出來,結果后臺直接就掛了!

開發小哥一查,原來是內存溢出了,一年下來的的訂單量足足有1000W條。于是,開發小哥跟產品汪吵了起來:你TM色不色傻,1000W的數據你導出來干diao,你是不是想把服務器給搞掛掉?

于是,產品汪與程序狗就這么結下梁子了。

但是。產品的需求你敢這樣懟回去,那如果是老板提的這個需求呢,就是硬要把1000W條記錄導出來,你還不得乖乖回去碼代碼?

那么,這個如果真要導出這大量數據,該怎么做呢?開發中我們經常會使用框架來提高我們的開發效率,但也意味著框架會對一些數據進行封裝。

比如Yii2,當我們想獲取去年一年的訂單時,我們的代碼會這樣寫:

Order::find()->where("create_time between "2016-01-01" AND "2016-12-31"")->all();

當我們將上面代碼得到的結果集再拿去遍歷時,數據量一大,就會內存溢出。
原因是:Yii2中,對all方法進行了封將,將大量的數據存入了數組中,而遍歷大數據,必然會導致內存迅速上升。
那如何取出大量數據,而又不存到數組中呢?這就要用到了PHP中的迭代器:Iterator。如果有看過PDO::query的返回值類型的話,我們會發現,這個方法返回的PDOStatement,正是對Iterator的實現。關于Iterator,請自行腦補。

即然框架幫我們做了多余的封裝,那么我們就改用原生API來實現。以下是完整代碼

$sql = "select * from user";
$pdo = newPDO( "mysql:host=127.0.0.1;dbname=test", "root", "root" );
$pdo->setAttribute( PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
$rows = $pdo->query($sql);

$filename = date("Ymd").".csv";//設置文件名
header("Content-Type:text/csv");
header("Content-Disposition:attachment;filename={$filename}");
$out = fopen("php://output","w");
fputcsv(
    $out, [
        "id",
        "username",
        "password",
        "create_time"
    ]
);

foreach( $rows as $row ){
$line=[
    $row["id"],
    $row["username"],
    $row["password"],
    $row["create_time"]
];

fputcsv($out,$line);
}

fclose($out);
$memory=round((memory_get_usage()-$startMemory)/1024/1024,3)."M".PHP_EOL;
file_put_contents("/tmp/test.txt",$memory,FILE_APPEND);

在表中生成7位數量級的記錄,執行上面的代碼,通過查看內存使用,發現整個過程只占用了0.XM的內存,完全沒有任何內存溢出的現象。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/31623.html

相關文章

  • PHP利用PDO從mysql讀取大量數據處理(可做大量數據集的導出,業務調整等)

    摘要:環境適用場景需要處理一定數據集業務從讀取一定數據的業務導出一次需要處理一定的業務操作更新刪除等更多需要處理一定數據集的操作關鍵設置關鍵設置,如果不設置,依舊會從一次取出數據到里的游標屬性不是必須的生成器生成器,迭代數據操作本生成器可 環境 mysql: 5.6.34php: 5.6nginx: php-fpm 適用場景 需要處理一定數據集業務 從mysql讀取一定數據的業務導出 一次...

    宋華 評論0 收藏0
  • PHP的生成器

    摘要:它最簡單的調用形式看起來像一個申明,不同之處在于普通會返回值并終止函數的執行,而會返回一個值給循環調用此生成器的代碼并且只是暫停執行生成器函數。 0x01 寫在前面 本文主要介紹: Generator的簡單用法。 Generator的底層實現。 本文比較長,可能會耗費你比較多的時間。如果你比較了解Generator的用法,僅想了解底層實現,可以直接跳到底層實現部分。 本文分析的PH...

    LMou 評論0 收藏0

發表評論

0條評論

codergarden

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<