Skip to content

Commit 56b2b2b

Browse files
committed
C
1 parent d67e71c commit 56b2b2b

File tree

6 files changed

+76
-0
lines changed

6 files changed

+76
-0
lines changed

src/backend/access/heap/heapam.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,11 @@ initscan(HeapScanDesc scan, ScanKey key, bool keep_startblock)
327327
else
328328
scan->rs_nblocks = RelationGetNumberOfBlocks(scan->rs_base.rs_rd);
329329

330+
/**
331+
这段代码是 PostgreSQL 中用于优化表扫描的逻辑,
332+
特别是针对大表的顺序扫描(sequential scan)。
333+
它通过判断表的大小和相关标志位,决定是否启用批量读取(bulk-read)访问策略和同步扫描(synchronized scanning),以提高扫描性能。
334+
*/
330335
/*
331336
* If the table is large relative to NBuffers, use a bulk-read access
332337
* strategy and enable synchronized scanning (see syncscan.c). Although

src/backend/executor/execMain.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,15 @@ standard_ExecutorRun(QueryDesc *queryDesc,
383383
MemoryContextSwitchTo(oldcontext);
384384
}
385385

386+
/**
387+
对比一下End:
388+
特性 ExecutorFinish ExecutorEnd
389+
主要职责 完成查询逻辑的收尾工作 释放资源并关闭扫描器
390+
调用时机 查询逻辑完成后,但资源仍需保留 查询完全结束后,释放所有资源
391+
处理对象 延迟操作、未消费的元组 内存、文件句柄、扫描器等资源
392+
是否清理资源 不清理资源,仅完成逻辑 清理所有资源,确保系统状态一致
393+
典型场景 聚合计算的最终阶段、排序结果的生成 查询执行结束,无论成功或失败
394+
*/
386395
/* ----------------------------------------------------------------
387396
* ExecutorFinish
388397
*

src/backend/storage/buffer/freelist.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,13 @@ have_free_buffer(void)
180180
return false;
181181
}
182182

183+
/**
184+
StrategyGetBuffer 是 PostgreSQL 缓冲区管理器(Buffer Manager)中的一个核心函数,
185+
用于为 BufferAlloc() 提供下一个候选缓冲区。
186+
187+
其主要目标是找到一个未被任何进程固定(pinned)的缓冲区,以便可以安全地分配给新的请求。
188+
该函数实现了多种策略来选择缓冲区,包括从自由列表(freelist)中获取缓冲区和使用时钟算法(Clock Sweep Algorithm)扫描缓冲区。
189+
*/
183190
/*
184191
* StrategyGetBuffer
185192
*

src/backend/utils/adt/selfuncs.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2428,6 +2428,52 @@ eqjoinsel(PG_FUNCTION_ARGS)
24282428
PG_RETURN_FLOAT8((float8) selec);
24292429
}
24302430

2431+
/**
2432+
`eqjoinsel_inner` 是 PostgreSQL 中用于估算等值连接(equality join)选择性的重要函数。选择性是查询优化器用来估算连接结果大小的关键指标。该函数主要用于普通的内连接(inner join),但也可以应用于左连接(LEFT JOIN)和全连接(FULL JOIN),因为这些连接类型在选择性估算上没有显著差异。
2433+
(interma:另外树杰的书中也有对这个函数的详细介绍)
2434+
2435+
### 1. **函数的输入参数**
2436+
- **`opfuncoid` 和 `collation`**: 分别表示连接操作符的函数 OID 和排序规则,用于确定如何比较两个列的值。
2437+
- **`vardata1` 和 `vardata2`**: 包含两个连接列的统计信息。
2438+
- **`nd1` 和 `nd2`**: 分别表示两个列的基数(distinct 值的数量)。
2439+
- **`isdefault1` 和 `isdefault2`**: 指示统计信息是否为默认值(即缺乏实际统计数据)。
2440+
- **`sslot1` 和 `sslot2`**: 包含两个列的最常见值(MCV,Most Common Values)及其频率。
2441+
- **`stats1` 和 `stats2`**: 包含两个列的统计信息,包括空值比例等。
2442+
- **`have_mcvs1` 和 `have_mcvs2`**: 指示是否存在 MCV 列表。
2443+
2444+
### 2. **函数的核心逻辑**
2445+
函数根据是否有 MCV 列表分为两种处理方式:
2446+
2447+
#### **(1) 双方都有 MCV 列表**
2448+
- **匹配 MCV**: 遍历两个列的 MCV 列表,使用连接操作符检查哪些值可以匹配。匹配的值会累加其频率乘积,表示这些值的选择性。
2449+
- **未匹配 MCV**: 计算未匹配的 MCV 的频率,并假设它们与另一列的非 MCV 值随机匹配。
2450+
- **非 MCV 值**: 计算非 MCV 值的频率,并假设它们随机匹配另一列的非 MCV 和未匹配的 MCV 值。
2451+
- **选择性估算**: 从两个方向(列 1 和列 2)分别估算选择性,并取较小值作为最终选择性。这种方法可以更准确地处理数据分布不均的情况。
2452+
2453+
(interma: 再细问一下gpt,能给出形式化公式)
2454+
2455+
#### **(2) 缺少 MCV 列表**
2456+
- 如果没有 MCV 列表,函数假设非空值均匀分布,并使用以下公式估算选择性:
2457+
```
2458+
selec = MIN(1/nd1, 1/nd2) * (1 - nullfrac1) * (1 - nullfrac2)
2459+
```
2460+
其中,`nullfrac1` 和 `nullfrac2` 是两列的空值比例。
2461+
2462+
### 3. **关键实现细节**
2463+
- **MCV 匹配优化**: 使用 `FunctionCallInvoke` 调用连接操作符函数,避免重复初始化函数调用上下文。
2464+
- **概率裁剪**: 使用 `CLAMP_PROBABILITY` 确保概率值在 [0, 1] 范围内。
2465+
- **内存管理**: 使用 `palloc0` 分配临时内存,并在计算完成后释放。
2466+
2467+
### 4. **函数的输出**
2468+
函数返回一个 `double` 类型的值,表示等值连接的选择性。选择性是一个介于 0 和 1 之间的概率,表示连接结果的行数占笛卡尔积的比例。
2469+
2470+
### 5. **适用场景**
2471+
- **查询优化**: 查询优化器使用该函数估算连接操作的成本,从而选择最优的执行计划。
2472+
- **数据分布不均**: 函数通过 MCV 列表处理数据分布不均的情况,提高选择性估算的准确性。
2473+
2474+
### 6. **总结**
2475+
`eqjoinsel_inner` 是 PostgreSQL 查询优化器中处理等值连接选择性的核心函数。它通过结合统计信息(如 MCV 和空值比例)和假设均匀分布的模型,提供了灵活且高效的选择性估算方法。这种设计在处理数据分布不均的情况下尤为有效,同时也能在缺乏统计信息时提供合理的估算结果。
2476+
*/
24312477
/*
24322478
* eqjoinsel_inner --- eqjoinsel for normal inner join
24332479
*

src/include/executor/executor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,8 @@ ExecProject(ProjectionInfo *projInfo)
386386
*/
387387
ExecClearTuple(slot);
388388

389+
// 虽然 ExecEvalExprSwitchContext 的返回值被丢弃,
390+
// 但表达式的执行过程会将所有列的结果存储到 ExprState 的 resultslot 中
389391
/* Run the expression, discarding scalar result from the last column. */
390392
(void) ExecEvalExprSwitchContext(state, econtext, &isnull);
391393

src/include/nodes/nodes.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ typedef enum NodeTag
3030
#include "nodes/nodetags.h"
3131
} NodeTag;
3232

33+
/**
34+
这段代码和注释定义了一个宏 pg_node_attr,用于在 PostgreSQL 的节点(node)定义中添加额外的元信息。
35+
这些元信息主要由 gen_node_support.pl 脚本使用,用于生成与节点相关的支持代码,
36+
例如复制、比较、序列化和反序列化等功能。通过这些属性,开发者可以灵活地控制节点及其字段的行为。
37+
38+
NB: gp7中还没有实现这个宏
39+
*/
3340
/*
3441
* pg_node_attr() - Used in node definitions to set extra information for
3542
* gen_node_support.pl

0 commit comments

Comments
 (0)