|
|
db file sequential read 优化的核心是:减少单块读的次数(通过优化 SQL 和索引)+ 提高单块读的效率(通过缓存和存储优化)。优先从 SQL 和索引入手(成本低、见效快),再考虑存储和硬件层面的调整。
-----------
db file sequential read 等待事件通常与单块读操作相关(如索引扫描、表访问 by rowid 等),等待时间过长往往意味着磁盘 I/O 效率低或 SQL 执行计划不合理。优化可从以下几个方向入手:
1. 优化 SQL 语句与执行计划
---检查是否使用了低效索引:
若 SQL 大量通过索引扫描但返回数据量较大(超过表数据量的 10%-15%),可能更适合全表扫描(full table scan)。可通过 explain plan 或 v$sql_plan 查看执行计划,确认是否存在 "索引过度使用"。
---避免不必要的索引回表:
若查询仅需少量字段,可创建覆盖索引(包含查询所需的所有列),减少通过 rowid 回表读取数据块的操作。
比如:
-- 原查询需要回表获取col3
select col1, col2, col3 from t where col1 = 'xxx';
-- 创建覆盖索引,避免回表
create index idx_t_cover on t(col1) include (col2, col3);
---优化关联查询:
多表关联时,确保关联条件有合适的索引,避免因驱动表选择不当导致大量单块读。
2. 优化索引设计
---删除冗余或低效索引:
无用索引会增加 DML(insert/update/delete)的开销,同时可能导致优化器误选索引。可通过 v$index_usage 检查索引使用频率,删除长期未使用的索引。
---重建碎片化索引:
索引碎片化会导致扫描时需要读取更多数据块。可通过 alter index ... rebuild 重建索引,减少 I/O 次数:
alter index idx_t_col1 rebuild online; -- 在线重建,不阻塞DML
3. 减少物理 I/O 次数
---增加缓冲区缓存(buffer cache):
若频繁访问的数据块未被缓存,会导致大量物理读。可通过调整 db_cache_size 增大缓存(需结合内存情况),让更多数据保存在内存中:
alter system set db_cache_size = 4G scope=spfile; -- 需重启生效
---使用自动内存管理(AMM):
启用 memory_target,让数据库自动分配缓冲区缓存和共享池等内存区域,避免手动调整的盲目性:
alter system set memory_target = 16G scope=spfile;
4. 优化存储与 I/O 性能
---检查存储系统性能:
通过操作系统工具(如 iostat、vmstat)确认磁盘是否存在 I/O 瓶颈(如高 IOPS、高延迟)。若存储性能不足,可考虑:
迁移到更快的存储介质(如 SSD);
分散 I/O 负载(如将数据文件分布到不同物理磁盘)。
---调整数据文件布局:
将热点表(频繁访问的表)的数据文件与其他文件分离,避免 I/O 竞争。
5. 监控与定位具体瓶颈
---通过视图定位问题 SQL:
查询 v$session 和 v$sql 找到等待 db file sequential read 时间最长的 SQL:
select
s.sid, s.serial#,
sql.sql_text,
s.event,
s.seconds_in_wait
from
v$session s
join
v$sql sql on s.sql_id = sql.sql_id
where
s.event = 'db file sequential read'
order by
s.seconds_in_wait desc;
---分析数据块访问频率:
通过 v$bh 查看缓存中数据块的访问情况,判断是否有高频访问的块未被有效缓存。
|
|