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 关注
- 279 浏览
添加回答
举报