核心内容摘要
SEER‘S EYE预言家之眼模型解释性工具:可视化注意力机制洞察AI决策
Oracle优化SQL语句 — 语法知识点与
使用方法详解
环境准备Oracle数据库安装简要说明注意Oracle数据库安装较为复杂以下为简化版安装流程以 Oracle Database 21c Express Edition 为例。
下载 Oracle Database 21c XE官网地址https://www.oracle.com/database/technologies/xe-downloads.html支持平台Windows / Linux
安装步骤以 Windows 为例以管理员身份运行安装程序OracleXE21c_Win
exe设置SYS / SYSTEM 用户密码记住该密码选择安装路径默认即可安装完成后服务自动启动OracleServiceXEOracleXETNSListener
验证安装# 打开命令行sqlplus sys/your_password//localhost:1521/XE as sysdba若成功进入 SQL 提示符说明安装成功。
创建测试用户可选-- 以 sys 用户登录后执行CREATEUSERtest_user IDENTIFIEDBYtest123;GRANTCONNECT,RESOURCE,DBATOtest_user;
常规SQL语句优化
不用“*”代替所有列名✅ 原理SELECT *会读取所有列增加 I/O 和网络传输开销。
明确指定列可利用覆盖索引提升性能。
案例代码-- ❌ 不推荐SELECT*FROMemployees;-- ✅ 推荐只查询需要的字段SELECTemployee_id,first_name,last_name,salaryFROMemployees;
用 TRUNCATE 代替 DELETE清空整表时✅ 原理DELETE是 DML逐行删除并写日志可回滚但慢。
TRUNCATE是 DDL直接释放数据段不可回滚速度快不触发触发器。
⚠️ 注意TRUNCATE不能带WHERE条件。
需要DROP ANY TABLE权限通常 DBA 或表所有者。
案例代码-- 删除所有员工记录可回滚慢DELETEFROMemployees_temp;-- 清空整个表不可回滚快TRUNCATETABLEemployees_temp;
在确保完整性的情况下多用 COMMIT✅ 原理频繁COMMIT可释放 UNDO 段减少锁争用避免 ORA-1555 错误。
但不要过度提交影响事务一致性。
案例代码批量插入 分批提交DECLAREi NUMBER :0;BEGINFORrecIN(SELECTlevelASid,User_||levelASnameFROMdualCONNECTBYlevel
LOOPINSERTINTOusers(user_id,user_name)VALUES(rec.id,rec.name);i :i1;-- 每 1000 行提交一次IFMOD(i,
0THENCOMMIT;DBMS_OUTPUT.PUT_LINE(Committed ||i|| records);ENDIF;ENDLOOP;COMMIT;-- 提交剩余记录END;/
尽量减少表的查询次数✅ 原理多次访问同一表会增加逻辑读和物理读。
使用子查询、连接或分析函数合并操作。
案例代码-- ❌ 两次查询 employees 表SELECTCOUNT(*)FROMemployeesWHEREdepartment_id10;SELECTAVG(salary)FROMemployeesWHEREdepartment_id10;-- ✅ 一次查询完成SELECTCOUNT(*),AVG(salary)FROMemployeesWHEREdepartment_id10;
用 [NOT] EXISTS 代替 [NOT] IN✅ 原理NOT IN在子查询含NULL时返回空结果逻辑陷阱。
EXISTS使用半连接semi-join效率更高。
案例代码-- ❌ NOT IN若子查询有 NULL结果为空SELECTemployee_idFROMemployeesWHEREdepartment_idNOTIN(SELECTdepartment_idFROMdepartmentsWHERElocation_id
;-- ✅ 使用 NOT EXISTS安全且高效SELECTe.employee_idFROMemployees eWHERENOTEXISTS(SELECT1FROMdepartments dWHEREd.department_ide.department_idANDd.location_id
;
表连接优化
驱动表的选择✅ 原理驱动表Driving Table是嵌套循环连接中先被扫描的表。
应选择结果集小的表作为驱动表。
案例使用 /* LEADING */ 提示-- 假设 departments 表小employees 表大SELECT/* LEADING(d) */e.first_name,d.department_nameFROMemployees eJOINdepartments dONe.department_idd.department_idWHEREd.location_id1700;
WHERE 子句的连接顺序✅ 原理虽然 CBOCost-Based Optimizer会重排但清晰的写法有助于阅读和调试。
先写连接条件再写过滤条件。
案例-- 推荐写法SELECTe.first_name,j.job_titleFROMemployees eJOINjobs jONe.job_idj.job_idWHEREe.salary5000ANDj.job_titleLIKE%Manager%;
合理使用索引
何时使用索引列出现在WHERE、JOIN、ORDER BY、GROUP BY中。
高选择性列如主键、唯一ID。
避免在低选择性列如性别上建单列索引。
索引列和表达式的选择❌ 错误对列使用函数 → 索引失效-- 索引无法使用SELECT*FROMemployeesWHEREUPPER(last_name)KING;✅ 正确使用函数索引 或 改写条件-- 方式1创建函数索引CREATEINDEXidx_emp_upper_lastnameONemployees(UPPER(last_name));-- 方式2避免函数如果业务允许SELECT*FROMemployeesWHERElast_nameKing;-- 假设数据规范
选择复合索引主列✅ 原理复合索引(col1, col2, col
只在WHERE包含col1时有效最左前缀原则。
案例-- 创建复合索引CREATEINDEXidx_emp_dept_salONemployees(department_id,salary);-- ✅ 能用索引SELECT*FROMemployeesWHEREdepartment_id10ANDsalary5000;-- ✅ 能用索引只用到第一列SELECT*FROMemployeesWHEREdepartment_id10;-- ❌ 无法使用索引SELECT*FROMemployeesWHEREsalary5000;
避免全表扫描大表对大表百万行的查询必须有索引支持。
使用EXPLAIN PLAN验证是否走索引。