SQL语句优化数据库效率
(1)布尔值上的索引无效
例 :病区医嘱表 (bqyz) 中医嘱记费标志 (jfbz)
为布尔型,虽然在该列上建立索引,但要检索哪
些医嘱未曾记费,速度依然较慢。后来在做优化
时把 jfbz 数据类型改为 Number(1),再在该列上
重新创建索引,PB 程序配合修改,同样硬件下,
速度提高近 30 倍。
(2)隐式转换与索引失效
例 :出院病人信息表 (zy_brry) 中病人 ID
号 (zybrid) 字段定义为 varchar2 (10), 但在查询
时把该字段作为 number 类型以 where 条件传给
Oracle, 这样会导致索引失效。
错误的例子 :
SELECT *
FROM zy_brry
WHERE ZYBRID = 201209101;
正确的例子 :
SELECT *
FROM zy_brry
WHERE ZYBRID =‘201209101’;
(3)对索引列进行运算导致索引失效
例:住院收费项目 (zysfxm) 中项目金额 (xmje)
上建有索引,where 子句中对列的任何操作结果
都是在 S QL 运行时逐列计算得到的 , 因此它不得
不进行全表搜索 , 而没有使用该列上的索引。
错误的例子 :
SELECT *
FROM zysfxm
WHERE xmje/30=1000;
正确的例子 :
SELECT *
FROM zysfxm
WHERE xmje=1000*30;
如何创建索引,提高数据库执行效率
1)索引创建原则。在select操作占大部分的表上
创建索引;在where子句中出现最频繁的列上创建索
引;在选择性高的列上创建索引;复合索引的主列应
该是最有选择性的和where限定条件最常用的列;小于
5 M的表,最好不要使用索引来查询,表越小,越适合
用全表扫描。
2)索引使用原则。查询结果是所有数据行的5%以
下时,使用index查询效果最好;where条件中经常用
到表的多列时,使用复合索引效果会好于几个单列索
引;因为当SQL语句所查询的列全部都出现在复合索引
中时,此时由于Oracle只需要查询索引块即可获得所
有数据,当然比使用多个单列索引要快得多;索引利
于select,但对经常insert、delete尤其update的
表,会降低效率。
SQL编写原则
原则1
建议使用CBO(基于开销的优化器cost-based-
optimizer);对于任何SQL语句一定要考虑其性能;
通过查看执行计划来比较SQL语句的优劣,防止经验
主义;可以利用hint等功能,只在非常必要时才使用
hint:仅在对SQL的执行计划非常肯定地要使用hint时
才使用。
原则2
Where条件中等号左边不要引用函数;where条件中
对于不同的数据类型要做显示数据转换;NOT,!=,<>,||
不会用索引;not exists好于not in;Exists好于in;
用UNION代替DECODE;用UNION ALL代替UNION;用UNION
代替OR;RDER BY不要加表达式。
原则3
避免复杂的SQL语句,采用多条语句代替;避免不
必要的排序,使用Distinct、Group by、Order by等;
使用表的别名;连接多个表时, 把表的别名前缀于每个
column上,这样可减少解析的时间以及避免由column歧
义引起的语法错误。
原则4
使用复合索引的第一个列;及时commit释放资源,
回滚段上用于恢复数据的信息;commit不要太频繁;分
批处理、逐次提交。
原则5
分页;运算放在常量端;全表删除用truncate而不
用delete;删除大量数据的方法;更新大量数据时使用
临时表。
原则6
绑定变量ID=1 / ID=:V;硬分析/软分析:语法检
测、语义检查、检查共享池中是否有相同的语句存在,
如果存在,则重用共享池中的SQL的执行计划和优化策略
(软解析);如果不存在,则重新生成SQL的执行计划和
优化策略(硬解析)。