转载:PostgreSQL SQL的性能调试 方法3-- 查 看 执 行 计 划

转载:PostgreSQL SQL的性能调试 方法3-- 查 看 执 行 计 划,第1张

概述原文:http://blog.csdn.net/hantiannan/article/details/4517192 PostgreSQLSQL的性能调试 方法3-- 查 看 执 行 计 划 利用pgAdmin中的自带的 查看 执行计划工具。 我 们 用的最多的就是 这 个工具, 这 个工具因 为 不需要其他什么配置或安装。 这个工具也是PostgreSQL主打的调试工具。 1.下面简单介绍一下执 原文:http://blog.csdn.net/hantiannan/article/details/4517192
Postgresqlsql的性能调试方法3--
利用pgadmin中的自带的查看执行计划工具。用的最多的就是个工具,个工具因不需要其他什么配置或安装。
这个工具也是Postgresql主打的调试工具。
1.下面简单介绍一下执行计划结果的读法
①Explaining → WIDths
=# EXPLAIN SELECT oID FROMpg_proc;
query PLAN
------------------------------------------
Seq Scan on pg_proc
(cost=0.00..87.47 rows=1747 wIDth=4)
查询结果的所有字段的总宽度。这个参数并不是关键指标。每个字段的宽度定义如下:
 text [ n 文字]:n + 4
  varchar(n):n+1
  char(n):n+1
boolean:1
 bigint :8
 integer: 4
②Explaining → Rows
预测的行数。与实际的行数可能有出入,经常vacuum或者analyze的话,这个值和实际值将更加接近。
③Explaining → Cost
cost是比较重要的指标。例子中的cost=0.00..87.47有两个部分,启动时间(startup)=0.00和总时间(total)=87.47。单位是毫秒。这个指标也只是预测值。
启动时间也有解释为找到符合条件的第一行所花的时间。
④Explaining → Explain Analyze
想知道实际的执行时候的执行计划的话,用这个命令。
=# EXPLAIN ANALYZE SELECT oID FROM pg_proc;
query PLAN
------------------------------------------
Seq Scan on pg_proc
(cost=0.00..87.47 rows=1747 wIDth=4)
(actual time=0.077..17.082 rows=1747 loops=1)
Total runtime: 20.125 ms
loops:循环的次数。
Total runtime:总的时间
⑤Explaining → 执行计划运算类型
Seq Scan:扫描表。无启动时间。
IndexScan:索引扫描。无启动时间。
Bitmap IndexScan:索引扫描。有启动时间。
Bitmap HeapScan:索引扫描。有启动时间。
SubqueryScan:子查询。无启动时间。
TIDScan:ctID = …条件。无启动时间。
Function Scan:函数扫描。无启动时间。
nested Loop:循环结合。无启动时间。
MergeJoin:合并结合。有启动时间。
HashJoin:哈希结合。有启动时间。
Sort:排序,ORDER BY *** 作。有启动时间。
Hash:哈希运算。有启动时间。
Result:函数扫描,和具体的表无关。无启动时间。
Unique:disTINCT,UNION *** 作。有启动时间。
limit:liMIT,OFFSET *** 作。有启动时间。
Aggregate:count,sum,avg,stddev集约函数。有启动时间。
Group:GROUPBY分组 *** 作。有启动时间。
Append:UNION *** 作。无启动时间。
Materialize:子查询。有启动时间。

Setop:INTERCECT,EXCEPT。有启动时间。

下面是一个hash,hash join例子:
=# EXPLAIN SELECT relname,nspname FROM pg_class JOIN
pg_namespace ON (pg_class.relnamespace=pg_namespace.oID);
query PLAN
------------------------------------------------------------------------
Hash Join (cost=1.06..10.71 rows=186 wIDth=128)
Hash Cond:("outer".relnamespace = "inner".oID)
->Seq Scan on pg_class (cost=0.00..6.86 rows=186 wIDth=68)
->Hash (cost=1.05..1.05 rows=5 wIDth=68)
->Seq Scan on pg_namespace (cost=0.00..1.05 rows=5 wIDth=68)
两个表INNER JOIN和left OUTERJOIN接的候,个运算很常用的。个运算是先把外表中关联条件部分做一个哈希表,然后去和内部表关联。
下面是一个nested Loop例子:
=# SELECT * FROM pg_foo JOIN pg_namespace
ON (pg_foo.pronamespace=pg_namespace.oID);
query PLAN
----------------------------------------------------------------------
nested Loop (cost=1.05..39920.17 rows=5867 wIDth=68)
Join Filter:("outer".pronamespace = "inner".oID)
->Seq Scan on pg_foo (cost=0.00..13520.54 rows=234654 wIDth=68)
->Materialize (cost=1.05..1.10 rows=5 wIDth=4)
->Seq Scan on pg_namespace (cost=0.00..1.05 rows=5 wIDth=4)

两个表INNER JOIN和left OUTERJOIN连接的时候,这个运算是很常用的。这个运算是扫描外表,然后去内部找所符合条件的记录。

下面是对表关联的3种结合运算的概念图。

sql的性能调试方法3--查看执行计划" src="http://simg.sinaJs.cn/blog7style/images/common/sg_trans.gif">

哈希运算要做一张哈希表,如果外部的tb1的数据不是特别多的时候是比较快的。如果tb1相当大,这时候做一张可能话时候反而更多。

因为做的哈希表内存装不下,需要输出到硬盘,这样IO读取多了,速度就低下了。

合并查询对外部和内部表都要用两个表的关联字段各自做一张,并且还要排序。如果是已经拍好序的,速度是很快。这中运算有数据特大的时候

还有可能不如循环结合快。

因此我们有个别地方可能直接用系统默认的执行计划的话反而很慢。如果是那样的话,可以尝试强制改变执行计划。禁止使用hash结合或合并结合。

这个要具体问题具体分析。

2.强制改变执行计划

时候我们不想用系统默认的执行计划。这时候就需要自己强制控制执行计划。
禁止某种运算的sql语法:SETenable_运算类型=off;//或者=false
开启某种运算的sql法:SETenable_运算 =on;//或者=true
划可以改的运算方法如下:
–enable_bitmapscan
–enable_hashagg
–enable_hashjoin
–enable_indexscan
–enable_mergejoin
–enable_nestloop
–enable_seqscan
–enable_sort
–enable_tIDscan
如果我们只想改变当前要执行的sql的执行计划,而不想影响其他的sql的话。在设置sql里面加一个关键字session即可。
例子: setsessionenable_hashjoin=false//禁止使用哈希结合算法
查看执行计划,我们就能够找到sql中的哪部分比较慢,或者说花费时间多。然后重点分析哪部分的逻辑,比如减少循环询,或者强制改变执行计划。
总结

以上是内存溢出为你收集整理的转载:PostgreSQL SQL的性能调试 方法3-- 查 看 执 行 计 划全部内容,希望文章能够帮你解决转载:PostgreSQL SQL的性能调试 方法3-- 查 看 执 行 计 划所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1177048.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存