1. 程式人生 > php教程 > PHP/MYSQL 查詢大資料/遍歷表_PHP教程

PHP/MYSQL 查詢大資料/遍歷表_PHP教程

PHP:PHP 5.3.6 (cli) (built: Jun 15 2011 16:29:50)

MYSQL:5.1.51

如果我們有的一張表有幾百萬或幾千萬的記錄,我們要使用 PHP 將所有的記錄都獲取過來(遍歷資料表)進行處理。查詢語句:

SELECT * FROM largetable;

PS:為了證明上面的做法是最佳的辦法,我嘗試使用 largetable 中的一個欄位做 where ,以及 LIMIT,OFFSET 。上面那種 WHERE 獲得結果很慢,雖然用了索引。後面這種 LIMIT 可以讓你有一種想死的感覺(有興趣可以瞭解下,《分頁優化》)。

以 MYSQL 以及PDO_MYSQL 為例,嘗試直接使用以下程式碼,必然會出現超記憶體的情況:

$result = mysql_query($sql);

while ($rowset = mysql_fetch_assoc($mysql)) {

...

$stmt = $dbh->prepare($sql);

$stmt->execute();

while ($row = $stmt->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT)) {

...

原因在於在查詢執行後,PHP 的MYSQL、PDO_MYSQL 將查詢結果全部快取到了客戶端,也就是 PHP 執行所在機器上。這樣如果我們要 SELECT * FROM LARGETABLE 查詢的記錄在 百萬以上的時候 ,快取的結果就會非常大,超出 PHP 使用記憶體。所以為了避免這樣情況就需要關閉客戶端的快取。

這裡提供二個測試指令碼,分別為 MYSQL、PDO_MYSQL 關閉快取後查詢樣例。點選下載:mysql_query

以下是 PDO_MYSQL 在查詢 ~100W 以及 ~200W (540M)資料結果(因為我的 PHP 記憶體使用設定了1G所以沒掛:) )

可以很明顯的看出在快取結果後佔用記憶體驚人…,當我們處理千萬資料的時候必掛。

PHP/MYSQL 查詢大資料/遍歷表_PHP教程

以下是 PDO_MYSQL 關閉快取查詢 ~200W 的資料結果。這下處理千萬以及E級的資料的時候,對記憶體表示很淡定。

PHP/MYSQL 查詢大資料/遍歷表_PHP教程

PS:如果你要處理的資料就幾十萬,你還是調大點記憶體好了。比如 MYSQL:

mysql_unbuffered_query() 的好處是有代價的:在 mysql_unbuffered_query() 返回的結果集之上不能使用 mysql_num_rows() 和 mysql_data_seek()。此外在向 MySQL 傳送一條新的 SQL 查詢之前,必須提取掉所有未快取的 SQL 查詢所產生的結果行。