我有如下的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
的车辆。
但是问题是查询需要很长时间才能执行。
有什么办法可以更好地编写它,以便更快地执行?
答案 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)