PG-EXPLAIN基础
熟悉sql的都知道EXPLAIN可以查看当前sql的查询计划及使用的扫描类型,下面我们就来讲讲PG中EXPLAN返回内容。
PG - EXPLAIN基础
在PG执行EXPLAIN后,返回的是一个计划结点的树。最底层的结点是扫描结点:它们从表中返回未经处理的行。
如果查询需要连接、聚集、排序、或者在未经处理的行上的其它操作,那么就会在扫描结点之上有其它额外的结点来执行这些操作,这些操作也可能出现不同的结点类型。
EXPLAIN会给计划树中每个结点都输出一行,显示基本的结点类型和规划器为该计划结点的执行所做的开销估计。 第一行(最上层的结点)是对该计划的总执行开销的估计;规划器试图最小化的就是这个数字。
EXPLAIN select * from user_info ;QUERY PLAN
-------------------------------------------------------------Seq Scan on user_info (cost=0.00..458.00 rows=10000 width=244)
常见的扫描类型有:
- 顺序扫描-Seq Scan
- 索引扫描-Index Scan
通过索引快速定位数据位置,再回表(Heap)读取完整行 - 位图索引扫描-Bitmap Heap Scan
- 仅索引扫描-Index Only Scan
索引包含查询所需的所有字段,无需回表
由于上述查询我们没有加任何where条件,所以它必须扫描表中的所有行,因此数据库规划器只能选择使用顺序扫描(类似mysql中的ALL)。被包含在圆括号中的数字含义从左至右分别是:
-
估计的启动开销。在输出阶段可以开始之前消耗的时间,例如在一个排序结点里执行排序的时间。
-
估计的总开销。这个估计值基于的假设是计划结点会被运行到完成,即所有可用的行都被检索。不过实际上一个结点的父结点可能很快停止读所有可用的行(见下面的LIMIT例子)。
-
这个计划结点输出行数的估计值。同样,也假定该结点能运行到完成。
-
预计这个计划结点输出的行平均宽度(以字节计算)。
开销的计算规则是根据PG配置中的页面读取数seq_page_cost和扫描的行数cpu_tuple_cost来决定的
seq_page_cost:
设置规划器计算一次顺序磁盘页面抓取的开销,默认为1cpu_tuple_cost:
设置规划器对一次查询中处理每一行的代价估计。默认值是 0.01。
计算规则为 开销 = (页面读取数seq_page_cost)+(扫描的行数cpu_tuple_cost)
回到我们的例子,现在我们在sql中加入where条件
EXPLAIN select * from user_info where a < 7000;QUERY PLAN
-------------------------------------------------------------
Seq Scan on user_info (cost=0.00..483.00 rows=7001 width=244)Filter: (a < 7000)
请注意EXPLAIN输出显示WHERE子句被当做一个“过滤器”条件附加到顺序扫描计划结点。 这意味着该计划结点为它扫描的每一行检查该条件,并且只输出通过该条件的行。
因为WHERE子句的存在,估计的输出行数降低了。不过,扫描仍将必须访问所有全表的10000行,因此开销没有被降低,反而还有所上升(准确来说,上升了 10000* cpu_operator_cost)以反映检查WHERE条件所花费的额外 CPU 时间。
以上就是如何查看EXPLAIN基础的返回内容,具体调优方向,还需要通过新增索引或者修改slow sql慢慢调试。