3 回答

TA貢獻1765條經驗 獲得超5個贊
該PDO::ATTR_PERSISTENT值不是布爾值。它標識正在使用的連接,對多個連接使用唯一值。就我而言:
$db = new PDO("mysql:host=".$dbhost.";dbname=".$dbname, $dbuser, $dbpass, array(PDO::ATTR_PERSISTENT => 'unbuff', PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false));
$db_ub = new PDO("mysql:host=".$dbhost.";dbname=".$dbname, $dbuser, $dbpass, array(PDO::ATTR_PERSISTENT => 'buff', PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true));

TA貢獻1836條經驗 獲得超3個贊
難道你不能通過簡單地運行一個查詢來擺脫大部分代碼:
?INSERT IGNORE INTO newtable
? ? ?SELECT? ...,
? ? ? ? ? ? ?IF(..., 5, 4)
? ? ? ? ?FROM oldtable WHERE ...;
這樣,您就可以擺脫 7G 內存問題。
如果結果證明一次做太多,那就把它分成塊。
另一個話題:為什么select somedata from users limit 1在循環內執行?似乎每次都得到相同的數據。此外,如果沒有ORDER BY,您將無法預測limit 1您將獲得哪一行。

TA貢獻1802條經驗 獲得超5個贊
您實際上是在進行 135000000 次查詢,而不是迭代 135000000 個對象。
將代碼更改為僅執行一個查詢,但對元素進行排序,就好像它們在您的 for 循環中一樣。
$db = new PDO("mysql:host=".$dbhost.";dbname=".$dbname, $dbuser, $dbpass, array(PDO::ATTR_PERSISTENT => true));
$stmt = $db->prepare('SELECT * FROM stats ORDER BY id ASC');
$stmt->execute();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
// ...
}
你甚至不需要這個if,它是數據庫本身可以更快使用的邏輯:
如果(!empty($row['id'])) {
反而:
SELECT * FROM stats WHERE id IS NOT NULL ORDER BY id ASC
我有一段時間沒有研究 PDO/MySQL,但我假設 unbuffered 允許你使用游標:
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
考慮到每個連接只能激活一個查詢。您基本上是在使用連接的緩沖區。
更好的選擇是在 map reduce 中只加載小塊。
SELECT * FROM stats LIMIT 100, 0
使用結果,然后
SELECT * FROM stats LIMIT 100, 100
- 3 回答
- 0 關注
- 347 瀏覽
添加回答
舉報