在PostgreSQL中,查询执行时常见的扫描方式有:
1. 全表扫描(Sequential Scan)(顺序扫描)
- 英文名称:
Seq Scan
- 说明:逐行扫描整张表数据,适用于小表或需要访问大部分数据的场景。当缺少有效索引或优化器认为全表扫描更高效时触发。
- EXPLAIN示例:
EXPLAIN SELECT * FROM users WHERE age > 30; -- 输出可能包含: Seq Scan on users (cost=0.00..12.50 rows=500 width=40)
2.并行顺序扫描(Parallel Seq Scan)
- 英文名称:
Parallel Seq Scan
- 说明:并行顺序扫描是传统全表扫描(Seq Scan)的并行化版本,通过多个工作进程(Worker)同时扫描表的不同数据块,最后汇总结果。通常当表的数据量超过一定阈值(如
min_parallel_table_scan_size
参数设置值),优化器可能选择并行扫描。 - EXPLAIN示例:
EXPLAIN ANALYZE SELECT COUNT(*) FROM large_table;
-- 输出示例:
Gather (cost=1000.00..4815404.03 rows=1 width=8)
Workers Planned: 2 -- 计划启动的并行进程数
-> Parallel Seq Scan on large_table (cost=0.00..4737279.02 rows=31250002 width=0)
- 关键节点:
Gather
表示并行协调,Parallel Seq Scan
表示实际的并行扫描。
3. 索引扫描(Index Scan)
- 英文名称:
Index Scan
- 说明:通过索引定位符合条件的行,再回表(Heap)读取完整数据。适合选择性高的查询(即索引过滤后需回表的数据量较少)。
- EXPLAIN示例:
EXPLAIN SELECT * FROM users WHERE id = 100; -- 输出可能包含: Index Scan using users_pkey on users (cost=0.15..8.17 rows=1 width=40)
4. 位图扫描(Bitmap Scan)
- 英文名称:
Bitmap Heap Scan
+Bitmap Index Scan
- 说明:分两阶段操作:
- Bitmap Index Scan:通过索引生成符合条件的行位置位图(内存中排序)。
- Bitmap Heap Scan:按位图顺序读取数据块,减少随机I/O。适合中等规模的数据筛选。
- EXPLAIN示例:
EXPLAIN SELECT * FROM users WHERE age BETWEEN 20 AND 30; -- 输出可能包含: -- Bitmap Heap Scan on users (cost=5.06..20.12 rows=100) -- -> Bitmap Index Scan on idx_users_age (cost=0.00..5.03 rows=100)
5. 仅索引扫描(Index-Only Scan)
- 英文名称:
Index Only Scan
- 说明:当查询所需字段全部包含在索引中时,直接读取索引数据,无需回表。需配合可见性映射文件(VM)确保数据可见性。
- EXPLAIN示例:
-- 假设索引包含 (age, name) EXPLAIN SELECT name FROM users WHERE age = 25; -- 输出可能包含: Index Only Scan using idx_users_age_name on users (cost=0.15..4.17 rows=10)
6. TID扫描(TID Scan)
- 英文名称:
TID Scan
- 说明:通过系统列
ctid
(物理行地址)直接定位数据行,通常用于已知行物理位置的查询(如通过ctid
条件)。 - EXPLAIN示例:
EXPLAIN SELECT * FROM users WHERE ctid = '(0,1)'; -- 输出可能包含: TID Scan on users (cost=0.00..4.01 rows=1)