【问题标题】:How to get Postgresql total cost time from explain如何从解释中获取 Postgresql 总成本时间
【发布时间】:2020-03-02 09:00:26
【问题描述】:

我在 postgresql 9.5 上有一个 sql 查询,但它需要的时间太长。然后我运行解释查询:

DELETE FROM source v1
    WHERE id < (SELECT MAX(id)
            FROM source v2
            WHERE v2.ent_id = v1.ent_id
            AND v2.name = v1.name
        );      

很明显是

Delete on source v1  (cost=0.00..1764410287608.21 rows=2891175 width=6)');
  ->  Seq Scan on source v1  (cost=0.00..1764410287608.21 rows=2891175 width=6)');
        Filter: (id < (SubPlan 2))');
        SubPlan 2');
          ->  Result  (cost=203424.76..203424.77 rows=1 width=0)');
                InitPlan 1 (returns $2)');
                  ->  Limit  (cost=0.43..203424.76 rows=1 width=8)');
                        ->  Index Scan Backward using source_id_ix on source v2  (cost=0.43..813697.74 rows=4 width=8)');
                              Index Cond: (id IS NOT NULL)');
                              Filter: (((ent_id)::text = (v1.ent_id)::text) AND ((name)::text = (v1.name)::text))');

我的表有大约 8.000.000 条记录。我好几天都没有得到结果。我无法计算需要多少次?有什么新的解决办法吗?

【问题讨论】:

    标签: postgresql sql-delete postgresql-9.5 postgresql-performance


    【解决方案1】:

    没有很好的方法来预测执行时间。

    作为一个非常粗略的经验法则,您可以将 1 的成本与在顺序扫描期间从磁盘读取一个 8 KB 页面的时间进行比较,但这通常会相差一个数量级以上。

    要解决根本问题,请尝试

    DELETE FROM source AS v1
    WHERE EXISTS (SELECT 1
                  FROM source AS v2
                  WHERE (v1.ent_id, v1.name) = (v2.ent_id, v2.name)
                  AND v2.id > v1.id);
    

    您的查询的问题是它必须为找到的每一行执行昂贵的子选择,而我的可以执行半连接。查看我的查询的执行计划。

    【讨论】:

    • 感谢您的快速查询,它在 5 分钟内删除了 400 万条记录。但是我在帖子上的查询工作了大约几个小时。有什么区别?
    • 我在答案中添加了一些内容来解决这个问题。
    猜你喜欢
    • 2014-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-10
    • 1970-01-01
    • 2012-12-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多