代码之家  ›  专栏  ›  技术社区  ›  Miles M.

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

  •  1
  • Miles M.  · 技术社区  · 7 年前

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

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

    https://knpuniversity.com/screencast/symfony-fundamentals/caching

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

    我有大量数据要从我的数据库中提取,这些数据需要缓存(使用大量左连接提取实体)。对于某些人来说,这些左连接是每小时、每天或每分钟定期更新的,通过cron job调用的bot(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 回复  |  直到 7 年前
        1
  •  1
  •   Flying    7 年前

    条令有几种类型的藏匿处:

    1. 对于类元数据(存储到数据库的类映射的位置)
    2. 用于查询(存储解析的DQL查询的位置)
    3. 查询结果(存储查询获取的实际结果)

    使用查询结果缓存和决定使用哪个缓存应取决于应用程序的逻辑。如果满足以下条件,您可以选择在案例中使用条令查询结果缓存:

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

    在这种情况下,条令查询结果缓存对您很有用,因为它对您的应用程序是透明的。它可能只对某些查询有用,因为您可以根据每个查询控制条令缓存的使用和生存期。

    在这种情况下,如果在将结果存储到缓存中之前需要对从数据库中获取的结果应用一些进一步的处理,或者需要应用一些附加逻辑来确定缓存内容是否过时,则最好使用Symfony缓存,因为它是特定于应用程序的,并且可以由您控制。