select * 在大数据量表中严重拖慢查询性能,因需读取传输所有字段,尤其含大字段时i/o和网络开销剧增;还会禁用hot优化,加剧mvcc膨胀。

为什么 SELECT * 在大数据量表里会拖垮查询性能
因为数据库要读取、传输、序列化每一列,哪怕你只用其中一两个字段。尤其当表里有 TEXT、JSONB 或多个大字段时,I/O 和网络开销会指数级上升。
- 真实场景:某日志表 20 亿行,含
user_agent(平均 800 字节)和event_payload(JSON,平均 12KB),SELECT *平均耗时 47s;只查id,created_at降到 1.2s - 注意:
SELECT *还会阻止 PostgreSQL 的 Heap-Only Tuple(HOT)优化,加剧 MVCC 膨胀 - 某些 ORM 默认生成
SELECT *,务必检查生成的 SQL,用.only()(Django)或显式字段列表替代
WHERE 条件没走索引?先看这三件事
不是建了索引就一定生效。大数据环境下,执行计划稍有偏差,就会从毫秒跳到分钟级。
- 类型不匹配:比如
WHERE user_id = '123'(字符串)对INT字段,会导致全表扫描 —— 改成WHERE user_id = 123 - 函数包裹字段:
WHERE to_date(created_at) = '2024-01-01'无法用created_at索引;改用范围查询:WHERE created_at >= '2024-01-01' AND created_at - 统计信息过期:
ANALYZE没跑过或数据突增后未更新,优化器会误判选择性 —— 大批量写入后记得手动ANALYZE table_name
分区表不是“开了就快”,关键在 WHERE 能否精准裁剪
PostgreSQL 的声明式分区(PARTITION BY RANGE)只有在查询条件能明确排除无关分区时才有效。否则它照样扫所有子表。
华友协同办公管理系统(华友OA),基于微软最新的.net 2.0平台和SQL Server数据库,集成强大的Ajax技术,采用多层分布式架构,实现统一办公平台,功能强大、价格便宜,是适用于企事业单位的通用型网络协同办公系统。 系统秉承协同办公的思想,集成即时通讯、日记管理、通知管理、邮件管理、新闻、考勤管理、短信管理、个人文件柜、日程安排、工作计划、工作日清、通讯录、公文流转、论坛、在线调查、
- 典型错误:按
created_at月分区,但查询写成WHERE EXTRACT(YEAR FROM created_at) = 2024—— 分区键被函数包裹,裁剪失效 - 正确写法必须包含可推导的分区边界,例如:
WHERE created_at >= '2024-01-01' AND created_at - 注意:跨分区查询(如最近 90 天)仍可能触发多分区扫描,此时考虑用
BRIN索引辅助,比 B-tree 更省空间且对时序数据友好
JOIN 顺序和驱动表选错,小表变瓶颈
大数据环境里,Nested Loop 配合错误的驱动表,会让一个 10 行的小表去循环匹配 1 亿行的大表 —— 结果是 10 亿次 IO。
- 用
EXPLAIN (ANALYZE, BUFFERS)看实际行数和 loops 值,重点盯Actual Rows×Loops是否远超预期 - 强制调整顺序:PostgreSQL 默认按
FROM顺序选驱动表,但可用/*+ Leading(t1 t2) */(需pg_hint_plan扩展)或重写JOIN为子查询控制 - 别迷信“小表驱动大表”:如果小表过滤后只剩 1 行,而大表有高效索引,那大表做内表反而更快 —— 关键看过滤后的基数,不是原始大小
真正卡住调优的,往往不是语法或配置,而是对数据分布和执行路径的误判。一个 EXPLAIN 里 Rows Removed by Filter 占比超过 95%,大概率说明 WHERE 条件写偏了,或者索引建错了位置。









