在这样的查询中:
SELECT
AVG(var1) AS var1_average,
AVG(var2) AS var2_average,
(
AVG(var1) +
AVG(var2)
)/2.0 AS total_average
FROM readings
像AVG(var1)这样多次出现的语句会被多次执行,还是在内部缓存更有效?
我的问题来自于试图理解性能/效率。把它写成某种形式的子查询会更好吗?会有多大的不同?
这是一个非常神秘的优化领域,即常见子表达式的优化。在您的示例中,它几乎没有什么区别。对group by
数据进行排序,这比做平均要贵得多。
还有其他计算,例如count(distinct)
,更昂贵。在这种情况下,您的问题变得更加明显。
在这种情况下,Stephen 与子查询进行比较的解决方案可能效果很好。但是,子查询本身会产生很多开销,因为它会创建一个临时表。所以,你不是在比较苹果和苹果。
如果你真的想比较差异,请进行以下比较。比较您的查询:
SELECT AVG(var1) AS var1_average, AVG(var2) AS var2_average,
(AVG(var1) + AVG(var2))/2.0 AS total_average
FROM readings;
至:
SELECT AVG(var1) AS var1_average, AVG(var2) AS var2_average
FROM readings;
您可能会发现它们花费的时间大致相同。如果没有,您也许可以使用子查询方法。或者您可能决定在应用程序级别进行平均计算。
尝试比较以下之间的执行时间:
SELECT
AVG(var1) AS var1_average,
AVG(var2) AS var2_average,
(
AVG(var1) +
AVG(var2)
)/2.0 AS total_average
FROM readings
和:
SELECT
(var1_average+var2_average)/2.0 AS total_average
var1_average,
var2_average
FROM (
SELECT
AVG(var1) AS var1_average,
AVG(var2) AS var2_average
FROM readings
) as tmp
确保多次运行它们并添加SQL_NO_CACHE
以获得有意义的结果。
注意:
第二个查询应该有一个小的开销,因为 mysql 将创建一个临时表,但如果表中有很多记录,这将无关紧要readings
。