SELECT SUM(price * quantity) as sales
FROM
(
SELECT price, quantity, date
FROM orderline
UNION ALL
SELECT price, quantity, date
FROM creditorderline
)
WHERE date BETWEEN '2010-01-01' AND '2016-01-01'
OR
SELECT SUM(price * quantity) as sales
FROM
(
SELECT price, quantity, date
FROM orderline
WHERE date BETWEEN '2010-01-01' AND '2016-01-01'
UNION ALL
SELECT price, quantity, date
FROM creditorderline
WHERE date BETWEEN '2010-01-01' AND '2016-01-01'
)
答案 0 :(得分:2)
第二种形式可能表现更好,原因有两个:
外部查询中的谓词不会被推入内联视图。因此,在内联视图中具有谓词的查询(即表中查询的WHERE
子句中的条件)有可能实现比第一个小得多的派生表查询。
对于各个表的查询(parens中的SELECT语句)的谓词,如果有适当的索引,MySQL可能能够使用有效的范围扫描操作。
鉴于日期值范围很大(5年),我猜测表中很大比例的行满足条件。这意味着您可能不会注意到两个提议的查询之间存在很大差异。
要查看两个查询之间的性能差异,需要满足以下几个条件:
1)WHERE子句中满足条件的行数需要比表中的所有行小得多
2)每个表都有date
作为第一列的索引。
"更好的查询和更快的"
的模式如果您正在寻找的是"更好"性能,然后使用这样的查询:
SELECT SUM(s.sales) AS sales
FROM ( SELECT SUM(o.price * o.quantity) AS sales
FROM orderline o
WHERE o.date BETWEEN '2010-01-01' AND '2016-01-01'
UNION ALL
SELECT SUM(c.price * c.quantity) AS sales
FROM creditorderline c
WHERE c.date BETWEEN '2010-01-01' AND '2016-01-01'
) s
内联视图中的每个SELECT都将返回一行,这可能比OP提供的任何查询选项都小得多。
鉴于日期范围很广(五年),我怀疑表中的行数占很大比例,因此索引不太可能有所帮助。如果这些谓词更具选择性,在表中提取一小部分行,则适当的索引可以提高性能。
... ON orderline (date,price,quantity)
... ON creditorderonline (date,price,quantity)
答案 1 :(得分:0)
很大程度上取决于索引。为什么不首先在orderline和creditorderline表中测试索引日期字段。正如其他人所建议的那样,这将给你最好的答案。