减少日期范围时,SQL查询需要更长的时间

时间:2014-02-03 07:14:33

标签: sql postgresql

我有一个包含日期范围的查询。

如果我在查询中将日期范围设为“>'2013-05-01'”,我会在188.300毫秒内得到结果。但是,如果我将日期范围更改为“BETWEEN'2013-05-01'''2013-08-01'”,我会在1102312.636 ms之后得到结果。这对我来说没有意义,因为第二个日期范围包含的数据少得多。

以下是2个查询及其解释:

SELECT 
SUM(quantity)
FROM
transaction_master
INNER JOIN transaction_line_items ON transaction_line_items.link_guid = transaction_master.guid
AND master_code = 'AAL027PU' and item_colour = 'BE'
AND (sale_date  > '2013-05-01')
AND transaction_type = 'POSSALE'

解释:http://explain.depesz.com/s/hPtI

SELECT 
SUM(quantity)
FROM
transaction_master
INNER JOIN transaction_line_items ON transaction_line_items.link_guid = transaction_master.guid
AND master_code = 'AAL027PU' and item_colour = 'BE'
AND sale_date BETWEEN '2013-05-01' AND '2013-08-01'
AND transaction_type = 'POSSALE'

解释:http://explain.depesz.com/s/WN1

谢谢!

2 个答案:

答案 0 :(得分:1)

查询计划的建议表明错误的行数估计,原因如下:

  • 分布不均匀且统计目标较低;

  • 过时的统计数据(autovacuum经常运行吗?)

  • 查询计划程序误估计

首先,运行ANALYZE。如果您需要手动执行此操作,则可能意味着autovacuum运行不足,或者您最近批量加载了一个表,而autovac尚未启动。

如果这没有用,请调整相关列的统计目标,以便分析更多行的样本。

如果您仍然得到相同的估算值,这可能表明规划人员误估了输入结合的方式。这更难处理;你需要将它报告给pgsql-performance并在那里寻求建议。

答案 1 :(得分:0)

您的条件适用于JOIN语句,我怀疑您应该添加WHERE子句。否则,服务器扫描所有表以查找具有匹配条件的记录,而不是先过滤掉所需的记录,然后再进行连接。当然,使用外键的简单连接只会更快。所以试试这个:

SELECT 
SUM(quantity)
FROM
transaction_master
INNER JOIN transaction_line_items ON transaction_line_items.link_guid = transaction_master.guid
WHERE
    master_code = 'AAL027PU' and item_colour = 'BE'
AND sale_date BETWEEN '2013-05-01' AND '2013-08-01'
AND transaction_type = 'POSSALE'