如何从解释中获取 Postgresql 总成本时间
How to get Postgresql total cost time from explain
我在 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 )');
-> 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))');
我的 table 有大约 8.000.000 条记录。我好几天都得不到结果。而且我无法计算需要多少次?有什么新的解决办法吗?
没有真正好的方法来预测执行时间。
作为一个非常粗略的经验法则,您可以将成本 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);
你的查询的问题是它必须为找到的每一行执行昂贵的子选择,而我的可以执行半连接。查看我的查询的执行计划。
我在 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 )');
-> 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))');
我的 table 有大约 8.000.000 条记录。我好几天都得不到结果。而且我无法计算需要多少次?有什么新的解决办法吗?
没有真正好的方法来预测执行时间。
作为一个非常粗略的经验法则,您可以将成本 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);
你的查询的问题是它必须为找到的每一行执行昂贵的子选择,而我的可以执行半连接。查看我的查询的执行计划。