5

在下面的这个例子中:

my $rs = $schema->resultset('CD')->search(
{
  'artist.name' => 'Bob Marley'
  'liner_notes.notes' => { 'like', '%some text%' },
},
{
  join     => [qw/ artist liner_notes /],
  order_by => [qw/ artist.name /],
}
);

DBIx食谱说这是将生成的 sql:

# Equivalent SQL:
# SELECT cd.*, artist.*, liner_notes.* FROM cd
# JOIN artist ON cd.artist = artist.id
# JOIN liner_notes ON cd.id = liner_notes.cd
# WHERE artist.name = 'Bob Marley'
# ORDER BY artist.name

但是从食谱的其余部分来看,我一直相信查询只会选择 cd.*,除非当然 prefetch 是这样使用的:

my $rs = $schema->resultset('CD')->search(
{
  'artist.name' => 'Bob Marley'
  'liner_notes.notes' => { 'like', '%some text%' },
},
{
  join     => [qw/ artist liner_notes /],
  order_by => [qw/ artist.name /],
  prefetch => [qw/ artist liner_notes/],
}
);

以下是让我相信这一点的陈述:

[Prefetch] allows you to fetch results from related tables in advance

谁能向我解释一下我在这里缺少什么?或不?非常感谢!

4

1 回答 1

4

这与食谱的前一部分Equivalent SQL相矛盾,看起来像是一个错误。

在执行查询并应用过滤器和排序条件时,Join 将使用连接表中的列,但它不会返回连接表的列。这意味着如果您这样做,那么每次您调用该语句时$cd->artist->name,它都需要执行额外的操作SELECT artist.* FROM artist WHERE artist.id = ?以获取艺术家的姓名。

预取也用于从预取表中选择所有列。当您实际需要这些列时,使用预取会更有效,例如,您可以在$cd->artist->name不需要它来执行附加查询的情况下执行此操作。但是,如果您不需要这些列,那么加载该数据就会对性能造成不必要的影响。

于 2012-06-18T03:09:05.947 回答