Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql Postgres query planner筛选顺序受使用“立即按顺序扫描”影响_Postgresql_Query Performance_Postgresql 12 - Fatal编程技术网

Postgresql Postgres query planner筛选顺序受使用“立即按顺序扫描”影响

Postgresql Postgres query planner筛选顺序受使用“立即按顺序扫描”影响,postgresql,query-performance,postgresql-12,Postgresql,Query Performance,Postgresql 12,我有一个查询,当在postgres数据库上启用顺序扫描并在where子句中使用now()时,查询计划器将倾向于对表进行顺序扫描,然后进行筛选: EXPLAIN ANALYZE SELECT action_id FROM events WHERE started_at IS NULL AND deleted_at IS NULL AND due_at < now()

我有一个查询,当在postgres数据库上启用顺序扫描并在where子句中使用now()时,查询计划器将倾向于对表进行顺序扫描,然后进行筛选:

    EXPLAIN ANALYZE
    SELECT
        action_id
    FROM
        events
    WHERE
        started_at IS NULL
        AND deleted_at IS NULL
        AND due_at < now()
        AND due_at > now() - interval '14 days'
    LIMIT 1
    FOR UPDATE
        SKIP LOCKED;


但是如果您有其他建议,我们将不胜感激

这两个查询都有相同的执行计划

不同之处在于,在从表中仅读取27行之后,带有常量的查询恰好快速找到与条件匹配的行

使用
now()
的查询在表中找不到任何匹配行(
actual rows=0
),但它必须扫描所有700万行才能确定


在处的
到期日上的索引应能显著提高性能。

两个查询具有相同的执行计划

不同之处在于,在从表中仅读取27行之后,带有常量的查询恰好快速找到与条件匹配的行

使用
now()
的查询在表中找不到任何匹配行(
actual rows=0
),但它必须扫描所有700万行才能确定


处的
到期日上的索引应该会大大提高性能。

如果使用
localtimestamp
而不是
now()
,会发生什么。。。而且发现吵架快多了缓存预热?(无论如何,这张8米长的桌子很可能会放在内存中)@a_horse_与_no_name没有预期的区别。@wildplasser是的,我想你是对的。在两个查询之间执行“放弃所有查询”级别。行估计值为关(800K vs 1)。您有有效的统计数据吗?如果您使用
localtimestamp
而不是
now()
。。。而且发现吵架快多了缓存预热?(无论如何,这张8米长的桌子很可能会放在内存中)@a_horse_与_no_name没有预期的区别。@wildplasser是的,我想你是对的。在两个查询之间执行“放弃所有查询”级别。行估计值为关(800K vs 1)。您是否有有效的统计信息?否,扫描将在找到尚未锁定且满足所有条件的行时立即停止。否,不再需要任何时间。也许你的例子不太好,你可以展示一个找到结果但仍然需要很长时间的例子。@Willeman:如果它是一个过滤索引,那么优化器可能更倾向于选择
due\u at
上的索引,例如
create index on events(due\u at),其中start\u at为null,deleted\u at为null
[顺便说一句:您的单表查询不应该是一个困难的情况。使用正确的数据模型和调整引擎应该选择正确的计划,而不需要任何调整]使用新内容编辑问题或询问新问题。不要忘记
解释(分析、缓冲区)
output。不,一旦发现一行尚未锁定且满足所有条件,扫描将立即停止。不,不再需要任何时间。也许您的示例不好,您可以显示一个找到结果但仍然需要很长时间的示例。@Willeman:如果它是作为一个过滤索引,例如,
在事件(到期日)上创建索引,其中start\u at为null,deleted\u at为null
[顺便说一句:单表查询应该不是一个困难的情况。使用正确的数据模型和调优,引擎应该选择正确的计划,而不进行任何调整]用新内容编辑问题或提出新问题。不要忘记
EXPLAIN(ANALYZE,BUFFERS)
output。
        SELECT 
            id,
            previous_event_id,
            due_at,
            action_id,
            subscription_url 
        FROM (
            SELECT 
                id, 
                previous_event_id, 
                due_at, 
                action_id, 
                subscription_url from events 
                WHERE 
                    started_at is null 
                    AND deleted_at is null
                LIMIT 100
                FOR update SKIP LOCKED
        ) events_to_pick_from
        WHERE EXISTS (
            SELECT 1
                FROM events
            WHERE
                events_to_pick_from.due_at < now()
                AND events_to_pick_from.due_at > now() - interval '14 days'
                AND events.action_id = events_to_pick_from.action_id
        )
        LIMIT 1
        FOR UPDATE SKIP LOCKED;