【问题标题】:DBIx::Class::ResultSet iterate over items new query every timeDBIx::Class::ResultSet 每次都迭代项目新查询
【发布时间】:2013-06-08 01:18:48
【问题描述】:

我正在使用DBIx::Class::ResultSet 来查询项目并对我的数据进行分页。这是我使用的查询:

my $clients = $c->model('DB::User')->search(
    { active_yn => 'y', client_yn => 'y' },
    {   
        columns => [qw/id first_name last_name username email/],
        order_by => ['last_name'],
        page     => ($c->req->param('page') || 1), 
        rows     => 20,
    }   
); 

一旦我得到结果集,我会像这样在Template::Toolkit 中循环遍历结果:

[% WHILE (client = clients.next) %]
    <tr>
        <td>[% client.first_name %] [% client.last_name %]</td>
    </tr>
[% END %]

我的问题是,每次我拨打next 时都会发出新的查询吗?我不清楚,因为all 方法说它返回集合中的所有元素,那么第一个查询不这样做吗?我想尽可能高效。谢谢!

【问题讨论】:

  • 在您的环境中设置 DBIC_TRACE=1,然后运行查询。您将看到正在生成的 SQL,并通过一些调试日志记录,您将能够将数据库访问与模型、视图或控制器操作相关联。
  • 这是个好建议。你知道我在哪里可以看到 DBIC_TRACE 的输出吗?我没有运行测试服务器,所以它不会进入 STDOUT。我用的是 nginx 和 fastcgi 都找不到。
  • 在开发/测试服务器下试一试。
  • 但输出通常会发送到 STDOUT,通常会发送到 Web 服务器上的错误日志。
  • 是的,Apache 通常就是这样。但是使用 nginx 我检查 /var/log/nginx/error.log 并没有显示任何查询。

标签: perl catalyst dbix-class


【解决方案1】:

答案是否定的:只要您使用相同的结果集实例,它就不会在您每次调用next 时执行新查询。它旨在成为一种快速迭代记录的方法。

【讨论】:

  • 太棒了!这就是我希望的答案:) 谢谢!
【解决方案2】:

搜索返回一个标量的 ResultSet 对象和一个列表上下文中的 Result 对象列表。 您可以使用 search_rs 强制返回 ResultSet。

如果您的数据库支持,Next 将使用游标,但每次调用仅获取一行并从中构造 Result 对象。

如果行数较少,执行单个 SQL 查询并一次构造所有 Result 对象会更快。 分页时通常是这种情况。

当构造所有 Results 对象的内存量太大时(例如导出数百万行时),Next 是有意义的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-11
    • 2017-05-17
    • 1970-01-01
    • 1970-01-01
    • 2011-09-12
    • 2016-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多