PostgreSQL中如何计算索引扫描的成本?
PostgreSQL中如何计算索引扫描的成本?
咱们来一步步拆解PostgreSQL里索引扫描成本的计算逻辑,结合你给出的参数和执行计划来具体说明:
首先,PostgreSQL是通过一组可配置的成本参数来估算查询成本的,你已经手动设置了这些关键参数,先明确它们的含义:
cpu_tuple_cost=0.01:处理一条表数据行的CPU成本cpu_index_tuple_cost=0.005:处理一条索引行的CPU成本cpu_operator_cost=0.0025:执行一次操作符(比如日期比较)的CPU成本seq_page_cost=1.0:顺序读取一个数据页的IO成本random_page_cost=4.0:随机读取一个数据页的IO成本enable_seqscan = off:强制数据库禁用全表扫描,只能走索引扫描
从你的执行计划来看,查询走的是Bitmap Heap Scan,这是分两步的成本计算:先完成Bitmap Index Scan(索引扫描阶段),再基于索引生成的bitmap去堆中读取数据(堆扫描阶段)。我们来拆解这两部分的成本:
一、索引扫描阶段的成本(对应执行计划里的cost=4.17)
PostgreSQL计算索引扫描成本的核心逻辑是:启动成本 + 索引页IO成本 + 索引行处理CPU成本 + 条件判断的操作符成本
结合你的参数和执行计划里估算的rows=3(数据库认为符合条件的行数是3),咱们来具体计算:
- 索引页IO成本:假设需要读取1个索引页(随机读取),成本是
1 * random_page_cost = 1*4.0 = 4.0 - 索引行处理成本:3条索引行的处理成本是
3 * cpu_index_tuple_cost = 3*0.005 = 0.015 - 条件判断成本:每一行都要做
d_slrq >= '2018-03-18'的比较,3行的成本是3 * cpu_operator_cost = 3*0.0025 = 0.0075 - 启动成本:数据库初始化索引扫描的固定小成本(约0.1475)
把这些加起来:4.0 + 0.015 + 0.0075 + 0.1475 = 4.17,正好对应执行计划里的索引扫描阶段总成本。
二、堆扫描阶段的成本(对应执行计划里的..10.31,即总成本减去索引扫描成本:10.31-4.17=6.14)
堆扫描的成本计算逻辑是:Bitmap处理成本 + 堆页IO成本 + 表行处理CPU成本 + 条件重检查成本
同样结合估算的3行数据计算:
- 堆页IO成本:假设需要读取1个堆数据页(随机读取),成本是
1 * random_page_cost = 4.0 - 表行处理成本:3条表数据行的处理成本是
3 * cpu_tuple_cost = 3*0.01 = 0.03 - 条件重检查成本:Bitmap扫描可能存在模糊匹配,需要重新验证条件,3行的成本是
3 * cpu_operator_cost = 0.0075 - Bitmap处理成本:将索引生成的bitmap转换为堆页读取指令的成本(约2.1025)
加起来:4.0 + 0.03 + 0.0075 + 2.1025 = 6.14,加上前面的索引扫描成本4.17,就得到了总成本10.31。
需要注意的是,这些都是数据库基于统计信息的估算值,你实际执行的rows=5和估算的3有差异,是因为统计信息可能不是最新的,但成本计算的逻辑是固定的。
内容的提问来源于stack exchange,提问作者dodo
相关产品推荐
相关产品推荐

