首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何提高KnpPaginatorBundle和原则的速度?

如何提高KnpPaginatorBundle和原则的速度?
EN

Stack Overflow用户
提问于 2015-08-08 16:41:35
回答 2查看 653关注 0票数 5

我有一个巨大的产品表(100k+行),在我的控制器中我有以下功能:

代码语言:javascript
复制
public function indexAction(Request $request)
    {
        $findProducts = $this->getDoctrine()
           ->getRepository("StockBundle:Product")->findAll();

        $paginator  = $this->get('knp_paginator');
        $producten = $paginator->paginate(
            $findProducts,
            $request->query->getInt('page', 1)/*page number*/,
            20/*limit per page*/
        );

        return $this->render('StockBundle:Default:index.html.twig', 
             array('producten' => $producten));
    }

问题是页面需要11到12秒的时间来加载和消耗233 of的RAM。

我能做些什么来提高速度和减少内存?

这是我的实体:

代码语言:javascript
复制
/**
 * Product
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Namespace\StockBundle\Entity\ProductRepository")
 */
class Product
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="naam_nl", type="string", length=255)
     */
    private $naamNl;

    /**
     * @var string
     *
     * @ORM\Column(name="naam_fr", type="string", length=255)
     */
    private $naamFr;

    /**
     * @var string
     *
     * @ORM\Column(name="naam_en", type="string", length=255)
     */
    private $naamEn;

    /**
     * @var string
     *
     * @ORM\Column(name="productnummer", type="string", length=255)
     */
    private $productnummer;

    /**
     * @var float
     *
     * @ORM\Column(name="prijs", type="float")
     */
    private $prijs;



    /**
     * @var string
     *
     * @ORM\Column(name="merk", type="string", length=255)
     */
    private $merk;

    /**
     * @ORM\OneToOne(targetEntity="Namespace\StockBundle\Entity\ProductInventory", cascade={"persist"})
     * @ORM\JoinColumn(name="productinventory_id", referencedColumnName="id")
     * 
     */
    private $productinventory;

表结构是由教义创建的,如下所示:

代码语言:javascript
复制
CREATE TABLE `product` (
  `id` int(11) NOT NULL,
  `naam_nl` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `productnummer` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `prijs` double NOT NULL,
  `merk` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `productinventory_id` int(11) DEFAULT NULL,
  `naam_fr` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `naam_en` varchar(255) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-08-08 17:29:27

现在,您正在调用findAll(),它将从数据库中检索所有记录,然后将它们合成成对象。这需要花费大量的时间,因为大多数这些对象都不会再次使用,因为一次只输出一个页面。

您应该做的是将一个查询生成器传递给分页器,然后它应该能够创建一个只获取当前页面实际需要的对象的查询。

代码语言:javascript
复制
public function indexAction(Request $request)
    {
        $findProducts = $this->getDoctrine()
           ->getRepository("StockBundle:Product")->createQueryBuilder("p");

        $paginator  = $this->get('knp_paginator');
        $producten = $paginator->paginate(
            $findProducts,
            $request->query->getInt('page', 1)/*page number*/,
            20/*limit per page*/
        );

        return $this->render('StockBundle:Default:index.html.twig', 
             array('producten' => $producten));
    }
票数 6
EN

Stack Overflow用户

发布于 2015-08-08 17:27:50

您最好使用Symfony2 profiler来调试您的查询,您应该首先使用add index on your fields和字段productinventory_id上的foreign key

索引可以像这样使用:

代码语言:javascript
复制
/**
 * @Entity
 * @Table(name="user",indexes={
 *     @Index(name="email_idx", columns={"email"})
 * })
 */
class User
{
    ...
}

要优化indexAction中的这个特定查询,您可以使用只需要在列表中显示的列进行选择,还可以编写查询而不是DQL查询。例如:

代码语言:javascript
复制
// Get connection
$conn = $entityManager->getConnection();

// Get table name
$meta = $entityManager->getClassMetadata(User::class);
$tableName = $meta->getTableName();

// Get random ids
$sql = "SELECT id AS id FROM $tableName WHERE active = true ORDER BY RAND()";
$statement = $conn->executeQuery($sql);
$ids = array_map(function ($element) {
    return $element['id'];
}, $statement->fetchAll());

return $ids;

最后,您应该启用像apcmemcache这样的缓存工具来释放sql服务器。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31896232

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档