Pagerfanta和Doctrine2 COUNT优化

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不运行嵌套查询?

Vig*_*jis 7

迟到总比没有好:我今天在同一面墙上打了超过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.

问题

相关提交