【问题标题】:SQL query very slow within Symfony, but very fast in PhpMyAdminSymfony 中的 SQL 查询非常慢,但在 PhpMyAdmin 中非常快
【发布时间】:2015-09-02 22:24:57
【问题描述】:

我正在开发一个商业智能应用程序。我在 Symfony 存储库中运行以下查询:

public function countSubscribers()
{
    $sql = "SELECT COUNT(DISTINCT(a.id))
    FROM account a
    INNER JOIN customer c ON c.account = a.id
    INNER JOIN payment p ON p.customer = c.id
    WHERE p.init != 1
    AND p.cancel_date IS NULL
    AND p.unpaid != 1
    AND p.abo = 1
    AND p.value != 0
    AND c.date_next_payement > NOW()";

    $connection = $this->getEntityManager()->getConnection();
    $statement = $connection->prepare($sql);
    $statement->execute();
    $result = $statement->fetchColumn();

    return $result;
}

页面加载很慢,根据 symfony 分析器,查询的执行时间超过 15 秒:

SELECT COUNT(DISTINCT(a.id)) FROM account a INNER JOIN customer c ON c.account = a.id INNER JOIN payment p ON p.customer = c.id WHERE p.init != 1 AND p.cancel_date IS NULL AND p.unpaid != 1 AND p.abo = 1 AND p.value != 0 AND c.date_next_payement > NOW() Parameters: { }
[Hide runnable query]
Time: 14553.83 ms [ - Explain query ]
Explanation:
id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
1   SIMPLE  c   ALL     PRIMARY,UNIQ_81398E097D3656A4               179226  Using where
1   SIMPLE  a   eq_ref  PRIMARY     PRIMARY     8   evotest.c.account   1   Using index
1   SIMPLE  p   ref     IDX_6D28840D81398E09    IDX_6D28840D81398E09    9   evotest.c.id    1   Using where

所以我尝试在 PhpMyAdmin 中运行这个查询,并且查询在不到 1 秒的时间内执行。知道为什么会有这样的差异吗?我的网页执行了一堆其他查询,但这是使用几乎所有总加载时间的查询。

更新查询:

SELECT COUNT(DISTINCT(c.id)) 
FROM customer c 
INNER JOIN payment p ON p.customer = c.id 
WHERE p.init != 1 
AND p.cancel_date IS NULL 
AND p.unpaid != 1 
AND p.abo = 1 
AND p.value != 0 
AND c.date_next_payement > NOW()

这个查询仍然很慢。有什么办法可以优化吗?我想用给定的过滤器计算至少有 1 笔付款的客户数量。关系在 c.id = p.customer

【问题讨论】:

  • 嗨,VaN,多次加入毁了我不止一个日子!您是否尝试过使用 DQL/Doctrine?也许它会更加优化,并有望按预期执行,因为它正在通过 DBAL。只是一个想法。
  • 我的第一次尝试是使用 DQL,但我认为 DQL 不可能比纯 SQL 更快,因为它是某种抽象层。所以我切换到SQL。但我会再试一次,看看它有多快。
  • 这可能是 MySQL 查询缓存吗? dev.mysql.com/doc/refman/5.5/en/query-cache.html
  • 试过 DQL,没有帮助。我用一个新查询更新了我的问题,其中删除了 1 个无用的连接。但它仍然很慢。有什么办法可以优化这个查询?
  • 查询慢的两个主要原因是 1) JOIN 和 2) WHERE 子句上的索引不足。由于您只有一个 JOIN,我会怀疑您的一个或多个 WHERE 子句没有索引并且必须进行全表扫描。如果此查询要执行很多,您可能会受益于基于此 WHERE 子句中 payment 中的所有 5 列创建单个索引。

标签: sql performance symfony doctrine-orm


【解决方案1】:

我会尝试使用EXISTS 进行子查询,而不是完全连接。

SELECT COUNT(1) 
FROM customer c
WHERE c.date_next_payement > NOW()
AND EXISTS (
  SELECT 1
  FROM payment p 
  WHERE p.customer = c.id 
  AND p.init != 1 
  AND p.cancel_date IS NULL 
  AND p.unpaid != 1 
  AND p.abo = 1 
  AND p.value != 0
);

【讨论】:

    猜你喜欢
    • 2016-12-17
    • 1970-01-01
    • 2015-05-22
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 2020-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多