SQL优化问题:
- 尽量使用列名取代* (*需要解析 耗内存 cup慢一点但是oracle9i之后都一样)
- 解析where是从右到左 尽量将为假的放在左边 为真的放在右边 注意and和or的左右顺序
- 尽量使用显示转换 (隐式转换的前提:被转换对象是可以转换的)
- 没有主函数时 where having 一样 尽量采用 where(where是先过滤再分组,效率高)
- 如果子查询和多表查询都可以使用的情况下,尽量使用多表查询(oracle对多表查询的优化)(理论上只查询一次,子查询 两次)
- 尽量不要使用集合运算
- Delete快于truncate (oracle的优化)
SQL语句中的null值
- 包含null值的表达式都为null //包含空值的表达式都为空值
- null != null -- 空值永远不等于空值
- 如果集合中含有null,不能使用not in;但是可以使用in
- 组函数自动滤空
查看执行计划
- explain plan for sql语句:
EXPLAIN PLAN FOR SELECT * FROM EMP
- plsql 查看计划
F5
:其实pl/sql developer工具内部执行查询 plan_table表然后格式化的结果。select * from plan_table where statement_id='...'
- sqldevelop 查看计划
F10
- Navicat 查看计划 点击
解释按钮
- Description中参数的解析
- 全表扫描(TABLE ACCESS FULL )
- 通过ROWID的表存取(TABLE ACCESS BY ROWID或rowid lookup)
- 索引扫描(TABLE ACCESS BY INDEX SCAN或index lookup)
(1) 索引唯一扫描(index unique scan)
(2) 索引范围扫描(index range scan)
在非唯一索引上都使用索引范围扫描。使用index rang scan的3种情况:
(a) 在唯一索引列上使用了range操作符(> < <> >= <= between)
(b) 在组合索引上,只使用部分列进行查询,导致查询出多行
(c) 对非唯一索引列上进行的任何查询。
(3) 索引全扫描(index full scan)
(4) 索引快速扫描(index fast full scan)
- 表之间的连接
1. 排序 - - 合并连接(Sort Merge Join, SMJ)
2. 嵌套循环(Nested Loops, NL)
3. 哈希连接(Hash Join, HJ)
另外,笛卡儿乘积(Cartesian Product)
执行顺序的原则
执行顺序的原则是:由上至下,从右向左
由上至下:在执行计划中一般含有多个节点,相同级别(或并列)的节点,靠上的优先执行,靠下的后执行
从右向左:在某个节点下还存在多个子节点,先从最靠右的子节点开始执行。
一般按缩进长度来判断,缩进最大的最先执行,如果有2行缩进一样,那么就先执行上面的。