• <li id="0bn34"><legend id="0bn34"><th id="0bn34"></th></legend></li>

      <label id="0bn34"><mark id="0bn34"><strong id="0bn34"></strong></mark></label>
      <span id="0bn34"><optgroup id="0bn34"></optgroup></span> <label id="0bn34"><mark id="0bn34"><strong id="0bn34"></strong></mark></label>

      <rt id="0bn34"></rt>
      <span id="0bn34"><optgroup id="0bn34"><center id="0bn34"></center></optgroup></span>
      <li id="0bn34"><big id="0bn34"><listing id="0bn34"></listing></big></li>
      PHP查詢MySQL海量數據內存占用分析
      • 更新時間:2025-06-07 14:08:33
      • 網站建設
      • 發布時間:2年前
      • 803

      PHP查詢MySQL大量數據的內存占用分析

      本文主要從原理、手冊和源碼分析PHP查詢MySQL時返回大量結果的內存占用問題,同時也涉及到MySQL C API的使用。

      昨天有同事在PHP討論組提到,他在做的一個項目,MySQL查詢返回的結果太多(最多10萬條),導致PHP內存不足。于是,他問,執行完下面的代碼遍歷返回MySQL結果之前,數據是否已經在內存中了? -

      while($row=mysql_fetch_assoc($result)){

      //.

      }

      當然,針對這類問題的優化方法有很多。不過,就這個問題,我首先想到的是MySQL是經典的C/S(Client/Server,客戶端/服務器)模型。在遍歷結果集之前,底層實現可能已經通過網絡(假設使用TCP/IP)將所有數據讀到客戶端緩沖區,還有一種可能是數據還在服務端的發送緩沖區中,并且已經沒有傳送給客戶端。

      之前看PHP和MySQL的源碼,注意到PHP手冊:中有兩個功能相似的函數

      mysql_查詢()

      mysql_unbuffered_query()

      這兩個函數的字面意思和描述證實了我的想法。執行前一個函數時,會將服務器端的所有結果集讀取到客戶端緩沖區,而后一個函數則不會。這就是“無緩沖(unbuffered)”的意思。

      也就是說,如果使用mysql_unbuffered_query()執行一個返回大結果集的SQL語句,在遍歷結果之前,PHP的內存是不會被結果集占用的。如果用mysql_query()執行同樣的語句,函數返回,PHP的內存占用會急劇增加,內存會馬上被耗盡。

      如果你看過PHP的相關代碼,就可以看出這兩個函數實現的異同:

      /*{{{protoresourcemysql_query(stringquery[,intlink_identifier])

      向MySQL 發送SQL 查詢*/

      PHP_FUNCTION(mysql_query)

      {

      php_mysql_do_query(INTERNAL_FUNCTION_PARAM_PASSTHRU,MYSQL_STORE_RESULT);

      }

      /*}}}*/

      /*{{{protoresourcemysql_unbuffered_query(stringquery[,intlink_identifier])

      向MySQL 發送SQL 查詢,不獲取和緩沖結果行*/

      PHP_FUNCTION(mysql_unbuffered_query)

      {

      php_mysql_do_query(INTERNAL_FUNCTION_PARAM_PASSTHRU,MYSQL_USE_RESULT);

      }

      /*}}}*/

      兩個函數都調用了php_mysql_do_query(),只是第二個參數不同,MYSQL_STORE_RESULT和MYSQL_USE_RESULT。查看php_mysql_do_query()的實現:

      如果(使用存儲==MYSQL_USE_RESULT){

      mysql_result=mysql_use_result(mysql-conn);

      }別的{

      mysql_result=mysql_store_result(mysql-conn);

      }

      mysql_use_result() 和mysql_store_result() 是MySQL C API 函數。這兩個C API函數的區別在于,后者是從MySQL Server讀取所有的結果集到Client,而前者只讀取結果集的元信息。

      回到PHP,使用mysql_unbuffered_query() 來避免直接內存占用。如果在遍歷過程中結果沒有被“PHP緩存”(比如放在一個數組中),雖然整個執行過程操作了10萬條或者百萬條或者更多的數據,但是PHP占用的內存總是很小的。

      標簽: 北京網站制作高端網站建設

      我們專注高端建站,小程序開發、軟件系統定制開發、BUG修復、物聯網開發、各類API接口對接開發等。十余年開發經驗,每一個項目承諾做到滿意為止,多一次對比,一定讓您多一份收獲!

      本文章出于推來客官網,轉載請表明原文地址:https://www.tlkjt.com/web/13828.html
      推薦文章

      在線客服

      掃碼聯系客服

      3985758

      回到頂部

      亚洲国产欧美精品一区二区三区| 中文精品久久久久国产网站| 日本特黄特色特爽大片老鸭| 亚洲mv国产精品mv日本mv| 最近中文字幕高清字幕8| 亚洲国产精品网| 晓雪老师下面好紧好湿| 二个人的视频www| 日本免费一区二区三区最新| 久久国产精品久久国产精品| 成年网站免费观看| 中文字幕乱码无线码在线| 女人毛片a级大学毛片免费| jizz大全欧美| 国产美女口爆吞精普通话| 91久久精品一区二区| 国产欧美日韩精品综合 | 亚洲熟妇av一区二区三区宅男 | 欧美日韩亚洲高清不卡一区二区三区| 亚洲男人的天堂久久精品| 欧美一级在线播放| 亚洲AV无码无在线观看红杏| 日本18xxx| 中文字幕亚洲欧美日韩高清| 天堂资源在线种子资源| 99久久精品久久久久久清纯| 国产福利91精品一区二区三区| 超碰97久久国产精品牛牛| 国产一区在线视频| 男生和女生一起差差差很痛的视频| 伊人久久精品一区二区三区| 欧美成人全部费免网站| 亚洲va在线va天堂va不卡下载| 日日碰狠狠添天天爽不卡| 中文天堂最新版www在线观看| 在镜子里看我怎么c你的| 91成人午夜在线精品| 国产在线麻豆精品观看| 精品国产一区二区三区不卡| 免费人成在线观看69式小视频| 欧美国产成人精品一区二区三区|