yef*_*rem 5 php mysql symfony doctrine-orm pagerfanta
我正在使用Pagerfanta和Doctrine Adapters与Symfony2和Silex.随着我的数据库变得越来越大,我发现管理员统计信息页面上的大量负载会显示带有分页的大数据.我检查了分析器,看到了令人难以置信的低效查询:
SELECT DISTINCT id16
FROM (
SELECT f0_.username AS username0, ..., f0_.added_on AS added_on20
FROM fos_user f0_ ORDER BY f0_.id DESC
) dctrn_result
LIMIT 50 OFFSET 0;
SELECT COUNT(*) AS dctrn_count
FROM (
SELECT f0_.username AS username0, ..., f0_.added_on AS added_on20
FROM fos_user f0_ ORDER BY f0_.id DESC
) dctrn_result
LIMIT 50 OFFSET 0;`
Run Code Online (Sandbox Code Playgroud)
通过创建DoctrineORMAdapter类的固定版本,可以轻松修复第一个查询.生成COUNT()查询的代码更复杂,所以我决定询问是否有任何解决方案.
那么有没有办法让Pagerfanta不运行嵌套查询?
迟到总比没有好:我今天在同一面墙上打了超过20万的记录并找到了解决方案.
Pagerfanta内部使用Doctrine\ORM\Tools\Pagination\CountOutputWalker来计算导致计数查询的对象,如下所示:
SELECT
COUNT(*) AS dctrn_count
FROM
(
SELECT
DISTINCT id_0
FROM
(
SELECT
m0_.id AS id_0,
...
FROM
messaging_messages m0_
ORDER BY
m0_.id DESC
) dctrn_result
) dctrn_table
Run Code Online (Sandbox Code Playgroud)
为了绕过CountOutputWalker,我们可以在实例化DoctrineORMAdapter时传递一个标志.而不是简单的
$adapter = new DoctrineORMAdapter($qb);
Run Code Online (Sandbox Code Playgroud)
你做
$adapter = new DoctrineORMAdapter($qb, true, false);
Run Code Online (Sandbox Code Playgroud)
(第三个参数).这会将计数查询转换为更有效的查询:
SELECT
count(DISTINCT m0_.id) AS sclr_0
FROM
messaging_messages m0_
Run Code Online (Sandbox Code Playgroud)
你必须将whiteoctober/Pagerfanta更新为1.0.3.