我有一个MySql查询
SELECT TE.company_id,
SUM(TE.debit- TE.credit) As summation
FROM Transactions T JOIN Transaction_E TE2
ON (T.parent_id = TE2.transaction_id)
JOIN Transaction_E TE
ON (TE.transaction_id = T.id AND TE.company_id IS NOT NULL)
JOIN Accounts A
ON (TE2.account_id=A.id AND A.deactivated_timestamp=0)
WHERE (TE.company_id IN (1,2))
AND A.user_id=2341 GROUP BY TE.company_id;
当我解释查询时,它的计划就像(摘要):
| Select type | table | type | rows |
-------------------------------------
| SIMPLE | A | ref | 2 |
| SIMPLE | TE2 | ref | 17 |
| SIMPLE | T | ref | 1 |
| SIMPLE | TE | ref | 1 |
但是如果我对同一个查询(而不是SUM(..))执行count(*),那么它会显示特定company_id有~40k行。我不明白的是,为什么查询计划显示在处理至少40k行时扫描如此少的行。查询计划中的rows列代表什么?它不代表在该表中处理的行数吗?在这种情况下,它应该至多2 * 17 * 1 * 1 = 34行?
答案 0 :(得分:0)
查询计划只显示对每个表所需的预期行数的高级判断,以满足最终结果。 它将被用作判断优化器如何看待'的工具。您的查询,并帮助它,以防查询性能更差或可以改进。
查询计划总是有可能是基于早期的统计快照构建的,因此不应该采用面值,特别是在处理基数时。
答案 1 :(得分:0)
好吧,首先让我们摆脱计算错误:
SELECT TE.company_id, TE.summation
FROM
( SELECT company_id,
SUM(debit - credit) As summation
FROM Transaction_E
WHERE company_id IN (1,2)
) TE
JOIN Transactions T ON TE.transaction_id = T.id
JOIN Transaction_E TE2 ON T.parent_id = TE2.transaction_id
JOIN Accounts A ON TE2.account_id = A.id
AND A.deactivated_timestamp = 0
WHERE A.user_id = 2341;
您的查询可能在执行GROUP BY
之前多次总结同一家公司。我的变体避免了总量的膨胀。
我摆脱了TE.company_id IS NOT NULL
,因为它是多余的。
请参阅EXPLAIN
对此的说明,然后让我们进一步讨论您关于EXPLAIN
的问题。