【发布时间】: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