问题描述
我按照本教程https://symfonycasts.com/screencast/doctrine-relations/pagination
但是我对执行简单的计数查询需要多长时间感到惊讶。
这是代码
$pagination = $paginator->paginate($manager->getRepository(
App::getProductClassForGroup($selected_group_code))->findAllWithCurrentUserOptions($user->getId()),$selected_page_number,$product_per_page,array('distinct' => false));
我在第四个参数中添加了array('distinct' => false)
,因为我使用外键作为主键(请参见this github issue)
$queryBuilder->addSelect('prod');
$queryBuilder->innerJoin($this->_alias . '.product','prod');
$queryBuilder->addSelect('users_bookmarks');
$queryBuilder->leftJoin('prod.users_bookmarks','users_bookmarks',Join::WITH,'users_bookmarks.id = :current_user_id');
$queryBuilder->setParameter('current_user_id',$current_user_id);
这是一个非常简单的查询,甚至没有任何where
子句或任何东西。
现在这是knp pagniator service
生成的查询:
102.11 ms
SELECT count(p0_.no_product_w2) AS sclr_0 FROM product_nat p0_ INNER JOIN product p1_ ON
p0_.no_product_w2 = p1_.no_product LEFT JOIN users_bookmark_products u3_ ON
p1_.no_product = u3_.product_no LEFT JOIN User u2_ ON u2_.id = u3_.user_id AND (u2_.id = ?)
Parameters:
[▼
1
]
EXPLAIN
SELECT count(p0_.no_product_w2) AS sclr_0 FROM product_nat p0_ INNER JOIN product
p1_ ON p0_.no_product_w2 = p1_.no_product LEFT JOIN users_bookmark_products u3_
ON p1_.no_product = u3_.product_no LEFT JOIN User u2_ ON u2_.id = u3_.user_id
AND (u2_.id = 1)
_________________________
# id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE p0_ index PRIMARY PRIMARY 36 24567 100.00 Using index
1 SIMPLE p1_ eq_ref PRIMARY PRIMARY 36 test.p0_.no_product_w2 1 100.00 Using index
1 SIMPLE u3_ ref IDX_A4705D7D9D172915 IDX_A4705D7D9D172915 36 test.p0_.no_product_w2 1 100.00 Using index
1 SIMPLE u2_ const PRIMARY PRIMARY 4 const 1 100.00 Using where; Using index
我在做什么错,为什么要花那么多时间?
计数查询花费这么长时间是正常现象吗?我不敢相信 其他网站正在如何管理分页?
分页的最佳实践是什么。
我已经尝试自己对分页进行计数,并且我做到了:
#Controller:index
$count_all_row = $manager->getRepository(App::getProductClassForGroup($selected_group_code))->countAll()
#Repository
/**
* Count all rows
* @param QueryBuilder|null $queryBuilder If no queryBuilder is provided,a new queryBuilder object is created
* @return int|null Number of rows
* @throws noresultException
* @throws NonUniqueResultException
*/
public function countAll(?QueryBuilder $queryBuilder = null): ?int
{
$queryBuilder ??= $this->createqueryBuilder($this->_alias,($this->_id) ? $this->_alias . '.' . $this->_id : null);
return $queryBuilder->select('COUNT(1)')->getQuery()->getSingleScalarResult();;
}
它的工作时间约为5.67毫秒,好得多。
5.67 ms
SELECT COUNT(1) AS sclr_0 FROM product_nat p0_
我的查询生成器非常简单,因为我只需要获取表包含的行数即可。
但是现在,如果我需要添加其他参数(例如,按标题搜索产品)或获取价格大于50 $的产品...,则需要修改countAll()
函数,并在我的函数中查找所有结果仓库...
每次修改仅计算标量结果的函数和获取数据结果的函数时,都不是一种好的做法。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)