Postgresql 比较 2 个查询以进行优化
我刚刚创建了几个查询,它们带来相同的数据,但数据不同。第一个使用子查询,第二个使用自连接策略。检查文档,我发现了 ANALYZE 和 EXPLAIN 命令,现在我试图了解哪个查询更好。这是每个查询的 EXPLAIN ANALYZE 的结果。希望有人能给我一些关于结果的解释,如果可能的话给我一些参考点,在哪里可以找到更多信息,坦克你。
EXPLAIN ANALYZE
SELECT historicoestatusrequisicion_id, requisicion_id, estatusrequisicion_id,
comentario, fecha_estatus, usuario_id
FROM historicoestatusrequisicion
WHERE requisicion_id IN
(
SELECT requisicion_id FROM historicoestatusrequisicion
WHERE usuario_id = 27 AND estatusrequisicion_id = 1
)
ORDER BY requisicion_id, estatusrequisicion_id;
这是结果
"Sort (cost=240.15..242.42 rows=906 width=58) (actual time=72.470..80.575 rows=3066 loops=1)"
" Sort Key: public.historicoestatusrequisicion.requisicion_id, public.historicoestatusrequisicion.estatusrequisicion_id"
" Sort Method: quicksort Memory: 436kB"
" -> Hash Join (cost=96.44..195.65 rows=906 width=58) (actual time=16.198..46.765 rows=3066 loops=1)"
" Hash Cond: (public.historicoestatusrequisicion.requisicion_id = public.historicoestatusrequisicion.requisicion_id)"
" -> Seq Scan on historicoestatusrequisicion (cost=0.00..78.66 rows=3066 width=58) (actual time=0.018..8.616 rows=3066 loops=1)"
" -> Hash (cost=95.45..95.45 rows=79 width=7) (actual time=16.132..16.132 rows=904 loops=1)"
" -> HashAggregate (cost=94.66..95.45 rows=79 width=7) (actual time=10.475..13.109 rows=904 loops=1)"
" -> Seq Scan on historicoestatusrequisicion (cost=0.00..93.99 rows=267 width=7) (actual time=1.309..5.329 rows=904 loops=1)"
" Filter: ((usuario_id = 27) AND (estatusrequisicion_id = 1))"
"Total runtime: 88.682 ms"
第二个查询
EXPLAIN ANALYZE
SELECT hist1.historicoestatusrequisicion_id, hist1.requisicion_id, hist1.estatusrequisicion_id, hist1.comentario, hist1.fecha_estatus, hist1.usuario_id
FROM historicoestatusrequisicion hist1
JOIN historicoestatusrequisicion hist2 ON hist2.requisicion_id = hist1.requisicion_id
WHERE hist2.usuario_id = 27 AND hist2.estatusrequisicion_id = 1
ORDER BY hist1.requisicion_id, hist1.estatusrequisicion_id;
这是结果
"Sort (cost=248.71..250.97 rows=906 width=58) (actual time=34.833..40.601 rows=3066 loops=1)"
" Sort Key: hist1.requisicion_id, hist1.estatusrequisicion_id"
" Sort Method: quicksort Memory: 436kB"
" -> Hash Join (cost=97.33..204.21 rows=906 width=58) (actual time=4.320..23.515 rows=3066 loops=1)"
" Hash Cond: (hist1.requisicion_id = hist2.requisicion_id)"
" -> Seq Scan on historicoestatusrequisicion hist1 (cost=0.00..78.66 rows=3066 width=58) (actual time=0.010..5.886 rows=3066 loops=1)"
" -> Hash (cost=93.99..93.99 rows=267 width=7) (actual time=4.289..4.289 rows=904 loops=1)"
" -> Seq Scan on historicoestatusrequisicion hist2 (cost=0.00..93.99 rows=267 width=7) (actual time=0.425..2.316 rows=904 loops=1)"
" Filter: ((usuario_id = 27) AND (estatusrequisicion_id = 1))"
"Total runtime: 46.387 ms"
I just created a couple of queries that bring the same data but in a different. the first one uses a sub query and the second one uses a self join strategy. checking the documentation, i found the ANALYZE and EXPLAIN commands, Now i'm trying to understand which query is better. this is the result of EXPLAIN ANALYZE for each query. Hope some one can give me some explanation about the result and if it is possible give me some point of reference where to find more information, tank you.
EXPLAIN ANALYZE
SELECT historicoestatusrequisicion_id, requisicion_id, estatusrequisicion_id,
comentario, fecha_estatus, usuario_id
FROM historicoestatusrequisicion
WHERE requisicion_id IN
(
SELECT requisicion_id FROM historicoestatusrequisicion
WHERE usuario_id = 27 AND estatusrequisicion_id = 1
)
ORDER BY requisicion_id, estatusrequisicion_id;
this is the result
"Sort (cost=240.15..242.42 rows=906 width=58) (actual time=72.470..80.575 rows=3066 loops=1)"
" Sort Key: public.historicoestatusrequisicion.requisicion_id, public.historicoestatusrequisicion.estatusrequisicion_id"
" Sort Method: quicksort Memory: 436kB"
" -> Hash Join (cost=96.44..195.65 rows=906 width=58) (actual time=16.198..46.765 rows=3066 loops=1)"
" Hash Cond: (public.historicoestatusrequisicion.requisicion_id = public.historicoestatusrequisicion.requisicion_id)"
" -> Seq Scan on historicoestatusrequisicion (cost=0.00..78.66 rows=3066 width=58) (actual time=0.018..8.616 rows=3066 loops=1)"
" -> Hash (cost=95.45..95.45 rows=79 width=7) (actual time=16.132..16.132 rows=904 loops=1)"
" -> HashAggregate (cost=94.66..95.45 rows=79 width=7) (actual time=10.475..13.109 rows=904 loops=1)"
" -> Seq Scan on historicoestatusrequisicion (cost=0.00..93.99 rows=267 width=7) (actual time=1.309..5.329 rows=904 loops=1)"
" Filter: ((usuario_id = 27) AND (estatusrequisicion_id = 1))"
"Total runtime: 88.682 ms"
Second query
EXPLAIN ANALYZE
SELECT hist1.historicoestatusrequisicion_id, hist1.requisicion_id, hist1.estatusrequisicion_id, hist1.comentario, hist1.fecha_estatus, hist1.usuario_id
FROM historicoestatusrequisicion hist1
JOIN historicoestatusrequisicion hist2 ON hist2.requisicion_id = hist1.requisicion_id
WHERE hist2.usuario_id = 27 AND hist2.estatusrequisicion_id = 1
ORDER BY hist1.requisicion_id, hist1.estatusrequisicion_id;
This is the result
"Sort (cost=248.71..250.97 rows=906 width=58) (actual time=34.833..40.601 rows=3066 loops=1)"
" Sort Key: hist1.requisicion_id, hist1.estatusrequisicion_id"
" Sort Method: quicksort Memory: 436kB"
" -> Hash Join (cost=97.33..204.21 rows=906 width=58) (actual time=4.320..23.515 rows=3066 loops=1)"
" Hash Cond: (hist1.requisicion_id = hist2.requisicion_id)"
" -> Seq Scan on historicoestatusrequisicion hist1 (cost=0.00..78.66 rows=3066 width=58) (actual time=0.010..5.886 rows=3066 loops=1)"
" -> Hash (cost=93.99..93.99 rows=267 width=7) (actual time=4.289..4.289 rows=904 loops=1)"
" -> Seq Scan on historicoestatusrequisicion hist2 (cost=0.00..93.99 rows=267 width=7) (actual time=0.425..2.316 rows=904 loops=1)"
" Filter: ((usuario_id = 27) AND (estatusrequisicion_id = 1))"
"Total runtime: 46.387 ms"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
分析器告诉您实际的执行路径是什么。对于第二个查询,
它根据estatusrequisicion ID对所有行进行排序,它使用快速排序来实现这一点。所用时间为 34 毫秒。
接下来,它在 hist1.requisicion_id = hist2.requisicion_id 上加入该结果集。由于这些是密钥,因此能够进行哈希查找。
哈希是主键/外键的存储方式。该字段被计算成哈希
查找速度为 1。
接下来,它使用另一个主/外键将结果集加入到历史状态请求中。
成本以任意单位进行测量,由规划者的 成本参数,实际时间是花了多长时间(实际花费)
执行计划的入门级解释
The analyzer is telling you what the actual execution path was. For the second query
It sorted all of the rows based off of the estatusrequisicion ID, it used quicksort to achieve this. The time it took was 34 ms.
It next joined that result set on the hist1.requisicion_id = hist2.requisicion_id. Since these are key's it was able to do a hash look up.
A Hash is how the primary/foreign keys are stored. The field is computed into a hash
and the lookup speed is 1.
Next it joined that result set on historicestatusrequisicion using another primary/foreign key.
The costs are measured in arbitrary units determined by the planner's cost parameters, actual time is how long (actual took)it took
decent entry level explanation of execution plans