更好的查询和更快

时间:2016-01-18 00:56:45

标签: mysql

我想在这两个查询之间询问,哪个查询更快?如果数据是20k到100k ..

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'
)

2 个答案:

答案 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表中测试索引日期字段。正如其他人所建议的那样,这将给你最好的答案。