getDoc-6ren">
gpt4 book ai didi

Symfony2/Doctrine 使 $statement->execute() 不是 "buffer"所有值

转载 作者:行者123 更新时间:2023-12-01 07:00:25 25 4
gpt4 key购买 nike

我有一个像这样的基本代码集(在 Controller 内):

$sql = 'select * from someLargeTable limit 1000';
$em = $this->getDoctrine()->getManager();
$conn = $em->getConnection();
$statement = $conn->prepare($sql);
$statement->execute();

我的困难是,当结果集只有几条记录时,内存使用情况还不错。我在运行 之前和之后回显了一些调试信息。 $语句->执行(); 部分代码,并为我的实现发现我有以下内容:
pre-execute... rowCount :: 0 memory: 49.614 MB
post-execute... rowCount :: 1000 memory: 50.917 MB

当从 1000 条记录上移到 10k 时,MB 使用量的差异增长到 13 MB
pre-execute... rowCount :: 0 memory: 49.614 MB
post-execute... rowCount :: 10000 memory: 62.521 MB

最终,检索大约 50k 条记录时,我接近了我的最大内存分配:
pre-execute... rowCount :: 0 memory: 49.614 MB
post-execute... rowCount :: 50000 memory: 114.096 MB

有了这个实现,我就无法编写一个 Controller (甚至是命令)来让我检索 CSV 数据。当然,50k+ 条目听起来很多,问题是为什么,但这不是问题。

我的最终问题是:是否可以告诉 DBAL/Connection 或 DBAL/Statement 在执行时缓冲 SQL 中的数据而不是整个 PHP 中的数据。例如,如果我有 1000 万行,只发送前 10k 行到 PHP...让我通过 来查看它们。 @statement->fetch(); 当光标到达 10k 的末尾时,截断数组并从数据库中获取下一个 10k?

最佳答案

我刚遇到同样的问题,想分享一个可能的解决方案。您的 DBAL 可能使用 PDO 库及其 PDO::MYSQL_ATTR_USE_BUFFERED_QUERY设置为 true 这意味着查询中的所有结果都缓存在 mysql 端并由 PDO 缓冲到内存中,即使您从未调用 $statement->fetchAll() .要解决这个问题,我们只需要设置 PDO::MYSQL_ATTR_USE_BUFFERED_QUERY为 false 但 DBAL 没有给我们提供方法 - 它的 PDO 连接类受到保护,没有公共(public)方法来检索它,它没有给我们使用 setAttribute 的方法在 PDO 连接上。

因此,在这种情况下,我只是使用自己的 PDO 连接来节省内存并加快速度。您可以使用您的学说数据库参数轻松地实例化一个,如下所示:

$dbal_conn = $this->getDoctrine()->getManager()->getConnection();
$params = $dbal_conn->getParams();
$pdo_conn = new \PDO(
'mysql:dbname='.$dbal_conn->getDatabase().';unix_socket='.$params['unix_socket'],
$dbal_conn->getUsername(),
$dbal_conn->getPassword()
);
$pdo_conn->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);

我使用的是 unix 套接字,但 IP 主机地址也可以轻松使用。

关于Symfony2/Doctrine 使 $statement->execute() 不是 "buffer"所有值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25660983/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com