sql 优化:
固定的SQL书写习惯,相同的查询尽量保持相同,存储过程的效率较高。
应该编写与其格式一致的语句,包括字母的大小写、标点符号、换行的位置等都要一致
sql语句用大写的;因为oracle总是先解析sql语句,把小写的字母转换成大写的再执行 .
写查询语句的时候,尽量不要出现 '*',把需要的列查询出来就可以。
1.尽量少用IN操作符,基本上所有的IN操作符都可以用EXISTS代替、not in 用not EXISTS代替.
特别注意:IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。 不是说所有的in或者not in 都可以用EXISTS和not EXISTS代替.
用IN来替换OR
这是一条简单易记的规则,但是实际的执行效果还须检验,在ORACLE8i下,两者的执行路径似乎是相同的.
低效:
SELECT…. FROM LOCATION WHERE LOC_ID = 10 OR LOC_ID = 20 OR LOC_ID = 30
高效
SELECT… FROM LOCATION WHERE LOC_IN IN (10,20,30);
用UNION替换OR (适用于索引列)
通常情况下, 用UNION替换WHERE子句中的OR将会起到较好的效果. 对索引列使用OR将造成全表扫描. 注意, 以上规则只针对多个索引列有效. 如果有column没有被索引, 查询效率可能会因为你没有选择OR而降低. 在下面的例子中, LOC_ID 和REGION上都建有索引.
高效:
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE LOC_ID = 10
UNION
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE REGION = “MELBOURNE”
低效:
SELECT LOC_ID , LOC_DESC , REGION
FROM LOCATION
WHERE LOC_ID = 10 OR REGION = “MELBOURNE”
如果你坚持要用OR, 那就需要返回记录最少的索引列写在最前面.
2.不用“<>”或者“!=”操作符。对不等于操作符的处理会造成全表扫描,可以用“<” or “>”代替 。
例如:
a<>0 改为 a>0 or a<0
a<>’’ 改为 a>’’
3.Where子句中出现IS NULL或者IS NOT NULL时,Oracle会停止使用索引而执行全表扫描。可以考虑在设计表时,对索引列设置为NOT NULL。这样就可以用其他操作来取代判断NULL的操作
用其它相同功能的操作运算代替,如:
1)a is not null 改为 a>0 或a>’’等。
2)不允许字段为空,而用一个缺省值代替空值,如业扩申请中状态字段不允许为空,缺省为申请。
3) 建立位图索引(有分区的表不能建,位图索引比较难控制,如字段值太多索引会使性能下降,多人更新操作会增加数据块锁的现象)
如果某列存在空值,即使对该列建索引也不会提高性能。任何在WHERE子句中使用is null或is not null的语句优化器是不允许使用索引的。
4、当通配符“%”或者“_”作为查询字符串的第一个字符时,索引不会被使用 .
例如: select u.name from user u where u.name like '%huang%'
应该改为: select u.name from user u where u.name like 'huang%'
5、对于有连接的列“||”,最后一个连接列索引会无效。尽量避免连接,可以分开连接或者使用不作用在列上的函数替代。
6、如果索引不是基于函数的,那么当在Where子句中对索引列使用函数时,索引不再起作用。
例如:creadate有索引
查询:select a.paicUmNum from ps_NumBer a where to_char(a.creadate,'yyyy-MM-dd')>'2010-10-12'不使用索引
select a.paicUmNum from ps_NumBer a where a.creadate>to_date('2010-10-12','yyyy-MM-dd')使用索引
7、Where子句中避免在索引列上使用计算,否则将导致索引失效而进行全表扫描。
例如:select s.numer from student s where s.age-20 = 50;
应该改为:select s.numer from student s where s.age = 30或者(50-20);
8、对数据类型不同的列进行比较时,会使索引失效。
例如:age为number类型 ,score 为varcher类型
select s.* from student s where s.age>score 在age和score 上的索引将会失效
避免改变索引列的类型.:
当比较不同数据类型的数据时, ORACLE自动对列进行简单的类型转换.
假设 EMPNO是一个数值类型的索引列.
SELECT … FROM EMP WHERE EMPNO = ‘123'
实际上,经过ORACLE类型转换, 语句转化为:
SELECT … FROM EMP WHERE EMPNO = TO_NUMBER(‘123')
幸运的是,类型转换没有发生在索引列上,索引的用途没有被改变.
现在,假设EMP_TYPE是一个字符类型的索引列.
SELECT … FROM EMP WHERE EMP_TYPE = 123
这个语句被ORACLE转换为:
SELECT … FROM EMP WHERE TO_NUMBER(EMP_TYPE)=123
因为内部发生的类型转换, 这个索引将不会被用到! 为了避免ORACLE对你的SQL进行隐式的类型转换, 最好把类型转换用显式表现出来. 注意当字符和数值比较时, ORACLE会优先转换数值类型到字符类型
9、采用UNION ALL操作符替代UNION,因为UNION ALL操作只是简单的将两个结果合并后就返回。UNION,在运行时先取出两个表的结果,再用排序空间进行排序删除重复的记录,最后返回结果集,如果表数据量大的话可能会导致用磁盘进行排序。
10.索引越多越好吗
索引是消耗存储空间的,索引太多会导致更新或者插入很慢,因为更新或者插入会同时更新插入索引。
11.总是使用索引的第一个列:
如果索引是建立在多个列上, 只有在它的第一个列(leading column)被where子句引用时,优化器才会选择使用该索引. 这也是一条简单而重要的规则,当仅引用索引的第二个列时,优化器使用了全表扫描而忽略了索引
12
在含有子查询的SQL语句中,要特别注意减少对表的查询.例子:
SELECT EMP_NO FROM EMP WHERE (GROUP,NAME) = ( SELECT
COLUMN1,COLUMN2 FROM TEST WHERE TEST_ID = 604)
最高效的删除重复记录方法 ( 因为使用了ROWID)例子:
DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID)
FROM EMP X WHERE X.EMP_NO = E.EMP_NO);
以上对sql的优化建议,都是通过本人亲身经历和点点滴滴总结出来的。如有不对的地方请指教。
收藏几个好的东西。
---用法很好。收藏
<!-- 查询已存在的审批实体生产架构的流水号 -->
<select id="searchAppEntityDeptId" parameterClass="java.util.Map"
resultClass="appEntityDeptDTO">
<![CDATA[
select t.entity_id appTempletId
from oms_entity_dept t
]]>
<isNotEmpty prepend="where" property="userList">
<iterate property="userList" conjunction="OR">
(t.dept_no = #userList[].deptNo# and t.entity_no = #userList[].entityNo#)
</iterate>
</isNotEmpty>
</select>
--ibatis调用proc
<!-- 调用存储过程,写人员生产信息表 -->
<parameterMap id="swapParameters" class="map">
<parameter property="paicUniqueDeptid" jdbcType="VARCHAR"
javaType="java.lang.String" mode="IN" />
<parameter property="paicUmNum" jdbcType="VARCHAR"
javaType="java.lang.String" mode="IN" />
</parameterMap>
<procedure id="swapEmailAddresses" parameterMap="swapParameters">
{call oms_sync_ps_pkg.proc_oms_prd_emp_io(?, ?)}
</procedure>
另附索引的一些概念(转载)
一、索引的概念
索引就是加快检索表中数据的方法。数据库的索引类似于书籍的索引。在书籍中,索引允许用户不必翻阅完整个书就能迅速地找到所需要的信息。在数据库中,索引也允许数据库程序迅速地找到表中的数据,而不必扫描整个数据库。
二、索引的特点
1.索引可以加快数据库的检索速度
2.索引降低了数据库插入、修改、删除等维护任务的速度
3.索引创建在表上,不能创建在视图上
4.索引既可以直接创建,也可以间接创建
5.可以在优化隐藏中,使用索引
6.使用查询处理器执行SQL语句,在一个表上,一次只能使用一个索引
三、索引的优点
1.创建唯一性索引,保证数据库表中每一行数据的唯一性
2.大大加快数据的检索速度,这也是创建索引的最主要的原因
3.加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
4.在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
5.通过使用索引,可以在查询的过程中使用优化隐藏器,提高系统的性能。
四、索引的缺点
1.创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加
2.索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大
3.当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度
五、索引分类
1.直接创建索引和间接创建索引
直接创建索引: CREATE INDEX mycolumn_index ON mytable (myclumn)
间接创建索引:定义主键约束或者唯一性键约束,可以间接创建索引
2.普通索引和唯一性索引
普通索引:CREATE INDEX mycolumn_index ON mytable (myclumn)
唯一性索引:保证在索引列中的全部数据是唯一的,对聚簇索引和非聚簇索引都可以使用
CREATE UNIQUE COUSTERED INDEX myclumn_cindex ON mytable(mycolumn)
3.单个索引和复合索引
单个索引:即非复合索引
复合索引:又叫组合索引,在索引建立语句中同时包含多个字段名,最多16个字段
CREATE INDEX name_index ON username(firstname,lastname)
4.聚簇索引和非聚簇索引(聚集索引,群集索引)
聚簇索引:物理索引,与基表的物理顺序相同,数据值的顺序总是按照顺序排列
CREATE CLUSTERED INDEX mycolumn_cindex ON mytable(mycolumn) WITH
ALLOW_DUP_ROW(允许有重复记录的聚簇索引)
非聚簇索引:CREATE UNCLUSTERED INDEX mycolumn_cindex ON mytable(mycolumn)
六、索引的使用
应该在这些列上创建索引,例如:
1在经常需要搜索的列上,可以加快搜索的速度;
2在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构;
3在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度;
4在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的;
5在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;
6在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。
不应该创建索引的的这些列具有下列特点:
第一,对于那些在查询中很少使用或者参考的列不应该创建索引。这是因为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。
第二,对于那些只有很少数据值的列也不应该增加索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。
第三,对于那些定义为text, image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少。
第四,当修改性能远远大于检索性能时,不应该创建索引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因此,当修改性能远远大于检索性能时,不应该创建索引。
分享到:
相关推荐
以下是对SQL优化的总结,主要聚焦于Oracle数据库的SQL语句调优。 1. **理解执行计划**:优化SQL的第一步是理解查询的执行计划。Oracle的`EXPLAIN PLAN`可以展示SQL执行的步骤,包括表扫描方式、连接顺序、索引使用...
接下来,"数据库SQL优化总结之百万级数据库优化.pdf"可能深入到实际的优化实践。 1. **数据库架构设计**:在百万级数据量下,合理的设计能避免性能瓶颈,如垂直分割、水平分割,以及读写分离策略。 2. **缓存与...
### SQL优化总结 #### 一、SQL优化的重要性 在数据库应用中,SQL查询性能的优劣直接影响着应用程序的响应时间和用户体验。高效的SQL查询不仅能够提升系统整体性能,还能减少服务器资源消耗,降低运营成本。因此,...
SQL优化总结.xmind
SQL语句优化是一项重要的数据库管理技能,能够显著提高数据库查询性能,减少资源消耗,缩短响应时间。以下是对上述文件内容中提及的关键知识点的详细总结: 1. 选择最有效的表名顺序 在使用基于规则的优化器时,...
Oracle数据库SQL优化是一个关键的技能,对于提升数据库性能和应用响应速度至关重要。以下是一些针对非DBA的Oracle SQL优化技巧: 1. **选择最有效的表名顺序**:在FROM子句中,应将记录最少的表放在最前面,基础表...
SQL语句操作,消耗了70%~90%的数据库资源; 独立于程序设计逻辑,相对于对程序源代码的优化,对SQL语句的优化在时间成本和风险上的代价都很低;
### SQL优化经验总结34条 #### 一、选择最有效率的表名顺序 - **要点**: 在基于规则的优化器(RBO)中,Oracle解析器从右至左处理FROM子句中的表名。为了提高性能,应将记录条数最少的表放在最后,即作为基础表。...
SQL优化是数据库性能提升的关键环节,它涉及到查询速度、资源消耗和系统稳定性等多个方面。以下是一些关于SQL优化的关键知识点: 1. **索引优化**: - 索引的合理使用至关重要,应确保主要的查询条件字段都有索引...
sql优化总结,对sql 优化在实战中对于sql优化的浅显理解,大神勿喷。
通过阅读"sql优化经验总结V1.5.ppt"和"sql优化经验总结.ppt",可以更深入地学习到更多实用技巧和案例分析,进一步提升在Oracle SQL优化方面的能力。不断学习和实践,才能在这个领域取得更大的成就。
数据库SQL优化大总结之百万级数据库优化方案 本文总结了数据库SQL优化的十一个重要知识点,以帮助开发者提高SQL查询效率,避免全表扫描。 一、数据库SQL优化之索引优化 1. 在where及order by涉及的列上建立索引,...
### SQL优化经验总结34条深度解读 #### (1) 最优表名顺序:提升查询效率 在基于规则的优化器中,Oracle按照从右至左的顺序处理FROM子句中的表名。为了提高查询效率,应将记录条数最少的表置于FROM子句的最后,作为...
16.4.2 优化总结 445 16.5 本章习题、总结与延伸 446 第17章 总结与延伸:从勿信讹传到洞若观火 447 17.1 SQL优化的各个误区 447 17.1.1 COUNT(*)与COUNT(列)的传言 447 17.1.2 谈SQL编写顺序之流言蜚语 451 ...
这篇博客"通过分析SQL语句的执行计划优化SQL(总结)"深入探讨了这一主题,下面将对其中的主要知识点进行详细阐述。 1. **执行计划的理解**: 执行计划是数据库管理系统在执行SQL语句之前预先生成的一种详细步骤,它...
- **全书总结**:本书不仅是一本关于SQL优化的技术书籍,更是引导读者进入SQL优化世界的指南。通过丰富的案例、实战经验和深入的技术探讨,帮助读者建立起从宏观到微观的优化思路,并最终达到“爽”的境界。 - **...