没用。DB_BLOCK_SIZE是实例级静态参数,启动后不可修改,调它等于重建数据库;提速应聚焦减少扫描量、提升I/O效率和优化执行计划,如加WHERE条件、建覆盖索引、分区裁剪、更新统计信息、避免SELECT*、换SSD等。
全表扫描慢,调大 DB_BLOCK_SIZE 真的有用吗?
没用。oracle 实例启动后,db_block_size 就固定了,不能动态修改,也不能只为某张大表单独设成 16k。它是一个实例级参数,影响所有默认表空间的数据块大小,改它等于重装库——不是优化手段,是重建成本。
DB_BLOCK_SIZE 改不了,那大表全扫还能怎么提速?
真正可落地的方向是让扫描更“少”、更“快”、更“准”,而不是幻想靠调块大小硬扛:
- 加合适的
WHERE条件 + 覆盖索引,避免真全扫; - 用分区表(如按时间范围
RANGE分区),让优化器自动裁剪掉无关分区; - 确认统计信息最新:
DBMS_STATS.GATHER_TABLE_STATS,否则优化器可能误判并拒绝走索引; - 检查是否用了
SELECT *—— 多读大字段(如CLOB、长VARCHAR2)会显著拖慢扫描吞吐,只查需要的列; - 确认 I/O 路径:如果表在机械盘上,再怎么调块大小也抵不过 SSD 的随机读优势。
什么时候才会看到 DB_BLOCK_SIZE 的实际影响?
只在建库初期或新建表空间时体现,且影响有限:
- 16K 块比 8K 块单次 I/O 读更多数据,对顺序读稍友好,但块越大,缓存命中率越容易下降(
DB_CACHE_SIZE不变时,能缓存的块数变少); - 高并发小事务场景下,16K 块反而增加行级锁争用概率(一个块里挤更多行);
- 已有数据库无法切换,新建表空间可用
BLOCKSIZE 16K,但表必须显式指定TABLESPACE ts_16k才生效,且该表空间只能放 16K 块对象,迁移成本不低; - 注意:
SYSTEM、SYSAUX表空间始终用默认DB_BLOCK_SIZE,没法换。
最容易被忽略的性能断点:不是块大小,是执行计划失真
很多 DBA 看到全表扫描就急着调底层参数,却漏看最上面一层:EXPLAIN PLAN 显示走了全扫,但根本原因是优化器认为走索引代价更高——而这往往是因为 WHERE 条件选择率预估错误,或者统计信息过期,或者隐式类型转换(比如把 NUMBER 字段和字符串 '123' 比较)导致索引失效。这类问题调 DB_BLOCK_SIZE 连边都碰不到。

















