PostgreSQL查询执行缓慢

时间:2019-03-06 10:23:09

标签: sql postgresql query-performance postgresql-performance

我有如下的PostgreSql查询:

SELECT DISTINCT ON (reference) reference, reference_url 
FROM vehicles v 
WHERE NOT EXISTS 
    (select reference 
     from daily_run_vehicle rv 
     WHERE ((
           handled = False 
           AND retries >= 5 ) 
           OR rv.timestamp::timestamp::date = now()::date)  
     AND v.reference=reference);

vehicles表具有约40万条记录,而daily_run_vehicle表具有约5000万条记录。

因此,我需要所有今天尚未添加到daily_run_vehicle或已处理列为False并重试column is >= 5的车辆。

但是问题是查询需要很长时间才能执行。

有什么办法可以更好地编写它,以便更快地执行?

2 个答案:

答案 0 :(得分:0)

我有一个理论,它可能与数百万次调用now()函数有关。 您可以通过运行此查询来验证

SELECT DISTINCT ON (reference) reference, reference_url 
FROM vehicles v 
WHERE NOT EXISTS 
    (select reference 
     from daily_run_vehicle rv 
     WHERE ((
           handled = False 
           AND retries >= 5 ) 
           OR rv.timestamp::timestamp::date = '2019-03-06')  
     AND v.reference=reference);

它的性能得到了改善,您必须将今天的日期设置为一个变量,并在查询中使用该变量,因此仅需调用1个now。 附带说明一下,如果您使用EXISTS,那么传统就是使用SELECT 1 FROM...。您不必关心值是仅存在一个还是不存在。

答案 1 :(得分:0)

嗯。我在想:

SELECT DISTINCT ON (v.reference) v.reference, v.reference_url 
FROM vehicles v 
WHERE NOT EXISTS (select 1 
                  from daily_run_vehicle rv 
                  where rv.reference = v.reference and
                        rv.handled = False and
                        rv.retries >= 5
                 ) and
      NOT EXISTS (select 1 
                  from daily_run_vehicle rv 
                  where rv.reference = v.reference and
                        rv.timestamp >= current_date::timestamp and
                        rv.timestamp >= (current_date + interval '1 day'::timestamp 
                 )
ORDER BY v.reference;

对于此查询,您希望在以下位置建立索引:

  • daily_run_vehicle(reference, handled, retries)
  • daily_run_vehicle(reference, timestamp)
  • reference_url(reference, reference_url)