Linux 上提升 SQL*Plus 性能的可操作清单
一 客户端显示与抓取参数优化
- 增大一次取回行数:提高 SET ARRAYSIZE(默认通常为 15,可调至数百或更高),可显著降低往返次数;注意值过大增加客户端内存占用,网络吞吐越高收益越大。
- 减少输出与抓取开销:关闭不必要的屏幕输出与提示,使用 SET FEEDBACK OFF、SET HEADING OFF、SET TERMOUT OFF(脚本批处理时)、SET SQLPROMPT ‘’;对 CLOB/LONG 等大字段,适当调小 SET LONG、SET LONGCHUNKSIZE。
- 去除冗余空白:开启 SET TRIMOUT ON、SET TRIMSPOOL ON,避免行尾空格占用带宽与磁盘;SET LINESIZE 设为“刚好容纳实际数据”,避免过宽导致内存拷贝与网络放大。
- 关闭脚本跟踪与变量解析:批处理时 SET APPINFO OFF;不需要替换变量时用 SET DEFINE OFF;不需要 DBMS_OUTPUT 时 SET SERVEROUTPUT OFF。
- 仅在需要时显示执行计划:使用 SET AUTOTRACE TRACEONLY 获取统计/计划而不打印结果集,避免大结果集打印拖慢脚本。
- 持久化常用设置:将常用 SET/COLUMN 写入 $ORACLE_HOME/sqlplus/admin/glogin.sql 或登录后用户级脚本,避免每次手工设置。
二 执行与脚本层面的效率技巧
- 使用静默与变量:脚本中用 sqlplus -S /nolog 配合 ACCEPT 或 Here Document 传参,减少交互与回显;避免在命令行中明文写密码。
- 合理假脱机:导出报表时 SPOOL 到文件,并在脚本开始/结束正确开关;配合 TRIMSPOOL ON、合理 LINESIZE 与列格式,减少文件体积与 I/O。
- 批量执行与管道:将多条语句放入 .sql 文件用 @ 执行;在 Shell 中通过管道/重定向驱动 SQL*Plus,减少终端渲染成本。
- 避免逐行打印:大数据量查询尽量不做逐行处理与逐行 DBMS_OUTPUT 打印;如确需输出,优先批量写入文件而非屏幕。
- 连接与会话:脚本开头 CONNECT 一次完成;必要时在脚本中 ALTER SESSION 设置 NLS_DATE_FORMAT、NLS_LANG 等,避免客户端反复解析与转换。
三 诊断与验证是否变快
- 打开计时:在会话中 SET TIMING ON,对比优化前后每条语句的“已用时间/CPU 时间”。
- 获取执行计划与统计:使用 SET AUTOTRACE ON/TRACEONLY 查看执行路径与统计信息;必要时先创建 PLAN_TABLE 并授予 PLUSTRACE 角色。
- 识别瓶颈:若“已用时间”远大于“CPU 时间”,多为 I/O 或网络往返瓶颈;优先增大 ARRAYSIZE、减少屏幕输出、压缩/去空白输出。
- 脚本级对比:对报表/批处理脚本,分别记录优化前后总耗时与资源占用,确保改动带来稳定收益。
四 数据库侧配合优化(SQL*Plus 只是客户端)
- 让优化器拿到正确统计:定期执行 DBMS_STATS.GATHER_TABLE_STATS 收集表和索引统计,避免错误计划。
- 访问路径优化:避免 SELECT ,只查需要的列;为高频过滤/关联列建立合适索引;大表按业务键做分区;必要时使用并行*执行。
- 减少解析开销:在应用/脚本中尽量使用绑定变量,降低硬解析比例。
- 会话级参数:在 SQL*Plus 中 ALTER SESSION 调整 SORT_AREA_SIZE、HASH_AREA_SIZE(或对应 PGA 自动管理设置)以匹配当前语句工作集。
五 常见误区与建议
- 把 ROWNUM 当作“性能旋钮”随意增大是误解;ROWNUM 是行号伪列,并不控制客户端取数批量大小,提升吞吐应优先调 ARRAYSIZE。
- 盲目增大 LINESIZE/ARRAYSIZE 可能适得其反:过大的值增加客户端内存与网络包大小,需结合字段宽度与带宽实测调优。
- 在 SQL*Plus 中做复杂格式化(如逐行拼接、频繁 DBMS_OUTPUT)会显著拖慢速度;报表导出建议直接 SPOOL 并在外部工具做展示。