首页 文章

如何在Symfony上正确缓存Doctrine 2查询?

提问于
浏览
1

我一直在广泛阅读Doctrine不同的缓存选项以及symfony缓存机制:

Symfony官方:https://symfony.com/doc/4.0/components/cache.html

主义官员:https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/caching.html

KnP大学(一如既往地非常有用):https://knpuniversity.com/screencast/symfony-fundamentals/caching

我应该使用Doctrine Cache还是Symfony 4缓存?哪一个可供选择?

我有大量的数据要从我的数据库中提取,我想缓存(拉动具有大量左连接的实体) . 对于某些人来说,左连接是每小时,每天或每分钟定期更新的用cron作业调用的机器人(symfony命令) .

/**
 * @return Coins[] Returns an array of Crypto objects
 */

public function findOneByTickerRelationnal($ticker)
{
    $em = $this->getEntityManager();
    $updatesrepository = $em->getRepository(Updates::class);
    $updates = $updatesrepository->findOneBy(['id'=> 1 ]);

    // This is where I’ve been doing additional work to limit my left join as much as possible with a ‘with’ on left join
    $recentMarkets = $updates->getMarket();
    $recentPrices = $updates->getPrice();
    $recentSources = $updates->getSources();

    $cryptos = $this->createQueryBuilder('c')
        ->select('partial c.{id, name, ticker}’) //<= use of partial is a plus but you need to know exactly which fields you want
        ->leftJoin('c.prices', 'p','WITH', 'p.last_updated >= :recentPrices')
        ->addSelect('partial p.{id, price_usd, daily_volume_usd, change_1h, change_1d, change_7d, rank}')
        ->leftJoin('c.markets', 'm','WITH', 'm.last_updated >= :recentMarkets')
        ->addSelect('partial m.{id, cur_supply, market_cap, max_supply}')
        ->leftJoin('c.sources', 's','WITH', 's.last_updated >= :recentSources')
        ->addSelect('s')
        ->where('c.ticker = :ticker')
        ->setParameter('recentPrices', $recentPrices)
        ->setParameter('recentMarkets', $recentMarkets)
        ->setParameter('recentSources', $recentSources)
        ->setParameter('ticker', $ticker)
        ->getQuery()
        ->getArrayResult(); //<=Changes everything 

    $results = $cryptos[0];

    return $results;
}

我不确定如何在考虑频繁更新的情况下正确缓存此查询 .

谢谢

1 回答

  • 1

    Doctrine有几种类型的缓存:

    • 用于类元数据(存储到数据库的类映射)

    • 用于查询(存储已解析的DQL查询)

    • 用于查询结果(存储查询提取的实际结果)

    前两种类型的Doctrine缓存与您的问题无关,因为它们特定于Doctrine,并且在Symfony中没有直接替代它们 . 查询结果缓存可以(间接)替换为Symfony缓存 .

    使用查询结果缓存和决定使用哪个缓存应该取决于应用程序的逻辑 . 如果满足以下条件,您可以更喜欢使用Doctrine查询结果缓存:

    • 您需要存储从数据库获取的原始数据(意味着它在存储到缓存之前不需要进一步处理)

    • 您的查询结果可以存储在缓存中一段特定的时间,并且在这段时间内不太可能变得陈旧

    在这种情况下,Doctrine查询结果缓存对您有用,因为它对您的应用程序是透明的 . 它可能仅对某些查询有用,因为您可以基于每个查询控制Doctrine缓存使用情况和生命周期 .

    如果您需要对从数据库中提取的结果进行进一步处理,然后再将其存储在缓存中,或者您还需要一些额外的逻辑来确定缓存内容是否过时 - 最好使用Symfony缓存,因为它特定于您的申请并可由您控制 .

相关问题