`
carvin
  • 浏览: 213472 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

如何写出性能优良的SQL

阅读更多
(1) 选择最有效率的表名顺序(只在基于规则的优化器中有效): 
ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最先处理,在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表。如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表. 
(2) WHERE子句中的连接顺序.: 
ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾. 
(3) SELECT子句中避免使用 ‘ * ‘: 
ORACLE在解析的过程中, 会将'*' 依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间 
(4) 减少访问数据库的次数: 
ORACLE在内部执行了许多工作: 解析SQL语句, 估算索引的利用率, 绑定变量 , 读数据块等; 
(5) 在SQL*Plus , SQL*Forms和Pro*C中重新设置ARRAYSIZE参数, 可以增加每次数据库访问的检索数据量 ,建议值为200 
(6) 使用DECODE函数来减少处理时间: 
使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表. 
(7) 整合简单,无关联的数据库访问: 
如果你有几个简单的数据库查询语句,你可以把它们整合到一个查询中(即使它们之间没有关系) 
(8) 删除重复记录: 
最高效的删除重复记录方法 ( 因为使用了ROWID)例子: 
DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID) 
FROM EMP X WHERE X.EMP_NO = E.EMP_NO); 
(9) 用TRUNCATE替代DELETE: 
当删除表中的记录时,在通常情况下, 回滚段(rollback segments ) 用来存放可以被恢复的信息. 如果你没有COMMIT事务,ORACLE会将数据恢复到删除之前的状态(准确地说是恢复到执行删除命令之前的状况) 而当运用TRUNCATE时, 回滚段不再存放任何可被恢复的信息.当命令运行后,数据不能被恢复.因此很少的资源被调用,执行时间也会很短. (译者按: TRUNCATE只在删除全表适用,TRUNCATE是DDL不是DML) 
(10) 尽量多使用COMMIT: 
只要有可能,在程序中尽量多使用COMMIT, 这样程序的性能得到提高,需求也会因为COMMIT所释放的资源而减少: 
COMMIT所释放的资源: 
a. 回滚段上用于恢复数据的信息. 
b. 被程序语句获得的锁 
c. redo log buffer 中的空间 
d. ORACLE为管理上述3种资源中的内部花费 
(11) 用Where子句替换HAVING子句: 
避免使用HAVING子句, HAVING 只会在检索出所有记录之后才对结果集进行过滤. 这个处理需要排序,总计等操作. 如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销. (非oracle中)on、where、having这三个都可以加条件的子句中,on是最先执行,where次之,having最后,因为on是先把不符合条件的记录过滤后才进行统计,它就可以减少中间运算要处理的数据,按理说应该速度是最快的,where也应该比having快点的,因为它过滤数据后才进行sum,在两个表联接时才用on的,所以在一个表的时候,就剩下where跟having比较了。在这单表查询统计的情况下,如果要过滤的条件没有涉及到要计算字段,那它们的结果是一样的,只是where可以使用rushmore技术,而having就不能,在速度上后者要慢如果要涉及到计算的字段,就表示在没计算之前,这个字段的值是不确定的,根据上篇写的工作流程,where的作用时间是在计算之前就完成的,而having就是在计算后才起作用的,所以在这种情况下,两者的结果会不同。在多表联接查询时,on比where更早起作用。系统首先根据各个表之间的联接条件,把多个表合成一个临时表后,再由where进行过滤,然后再计算,计算完后再由having进行过滤。由此可见,要想过滤条件起到正确的作用,首先要明白这个条件应该在什么时候起作用,然后再决定放在那里 
(12) 减少对表的查询: 
在含有子查询的SQL语句中,要特别注意减少对表的查询.例子: 
SELECT TAB_NAME FROM TABLES WHERE (TAB_NAME,DB_VER) = ( SELECT 
TAB_NAME,DB_VER FROM TAB_COLUMNS WHERE VERSION = 604) 
(13) 通过内部函数提高SQL效率.: 
复杂的SQL往往牺牲了执行效率. 能够掌握上面的运用函数解决问题的方法在实际工作中是非常有意义的 
(14) 使用表的别名(Alias): 
当在SQL语句中连接多个表时, 请使用表的别名并把别名前缀于每个Column上.这样一来,就可以减少解析的时间并减少那些由Column歧义引起的语法错误. 
(15) 用EXISTS替代IN、用NOT EXISTS替代NOT IN: 
在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接.在这种情况下, 使用EXISTS(或NOT EXISTS)通常将提高查询的效率. 在子查询中,NOT IN子句将执行一个内部的排序和合并. 无论在哪种情况下,NOT IN都是最低效的 (因为它对子查询中的表执行了一个全表遍历). 为了避免使用NOT IN ,我们可以把它改写成外连接(Outer Joins)或NOT EXISTS. 
例子: 
(高效)SELECT * FROM EMP (基础表) WHERE EMPNO > 0 AND EXISTS (SELECT ‘X' FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = ‘MELB') 
(低效)SELECT * FROM EMP (基础表) WHERE EMPNO > 0 AND DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = ‘MELB') 
(16) 识别'低效执行'的SQL语句: 
虽然目前各种关于SQL优化的图形化工具层出不穷,但是写出自己的SQL工具来解决问题始终是一个最好的方法: 
SELECT EXECUTIONS , DISK_READS, BUFFER_GETS, 
ROUND((BUFFER_GETS-DISK_READS)/BUFFER_GETS,2) Hit_radio, 
ROUND(DISK_READS/EXECUTIONS,2) Reads_per_run, 
SQL_TEXT 
FROM V$SQLAREA 
WHERE EXECUTIONS>0 
AND BUFFER_GETS > 0 
AND (BUFFER_GETS-DISK_READS)/BUFFER_GETS < 0.8 
ORDER BY 4 DESC; 
(17) 用索引提高效率: 
索引是表的一个概念部分,用来提高检索数据的效率,ORACLE使用了一个复杂的自平衡B-tree结构. 通常,通过索引查询数据比全表扫描要快. 当ORACLE找出执行查询和Update语句的最佳路径时, ORACLE优化器将使用索引. 同样在联结多个表时使用索引也可以提高效率. 另一个使用索引的好处是,它提供了主键(primary key)的唯一性验证.。那些LONG或LONG RAW数据类型, 你可以索引几乎所有的列. 通常, 在大型表中使用索引特别有效. 当然,你也会发现, 在扫描小表时,使用索引同样能提高效率. 虽然使用索引能得到查询效率的提高,但是我们也必须注意到它的代价. 索引需要空间来存储,也需要定期维护, 每当有记录在表中增减或索引列被修改时, 索引本身也会被修改. 这意味着每条记录的INSERT , DELETE , UPDATE将为此多付出4 , 5 次的磁盘I/O . 因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢.。定期的重构索引是有必要的.: 
ALTER INDEX <INDEXNAME> REBUILD <TABLESPACENAME> 
(18) 用EXISTS替换DISTINCT: 
当提交一个包含一对多表信息(比如部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT. 一般可以考虑用EXIST替换, EXISTS 使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立刻返回结果. 例子: 
(低效): 
SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D , EMP E 
WHERE D.DEPT_NO = E.DEPT_NO 
(高效): 
SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT ‘X' 
FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO); 
(19) sql语句用大写的;因为oracle总是先解析sql语句,把小写的字母转换成大写的再执行 
(20) 在java代码中尽量少用连接符“+”连接字符串! 
(21) 避免在索引列上使用NOT 通常,  
我们要避免在索引列上使用NOT, NOT会产生在和在索引列上使用函数相同的影响. 当ORACLE”遇到”NOT,他就会停止使用索引转而执行全表扫描. 
分享到:
评论

相关推荐

    DiaryManager

    在酒店管理系统的开发中,数据库的设计与管理是至关重要的,因为它们存储了所有关键的业务数据,如客户信息、房间状态、预订记录等。...通过不断学习和实践,我们可以成为既能编写正确SQL,又能写出性能优良SQL的专家。

    数据库优化从性能优良的SQL语句开始

    本文将深入探讨如何从编写性能优良的SQL语句开始进行数据库优化。 1. SQL基础与优化原则 - **理解索引**:索引是提升查询速度的重要工具,正确创建和使用索引可以大幅减少数据检索时间。了解B树、哈希索引等不同...

    SQL语句编写指导文档

    SQL语句编写指导文档旨在帮助开发者写出性能优良的SQL语句,提升程序执行效率。以下是一些关键点的详细解释: 1. **选择最有效率的表名顺序**:在基于规则的优化器中,查询优化器通常会根据表的顺序进行操作。因此...

    SQl优化34条[参考].pdf

    本文将详细介绍SQL优化的34条经验,旨在帮助读者写出性能优良的SQL语句。 (1)选择最有效率的表名顺序 在 FROM 子句中,ORACLE 的解析器按照从右到左的顺序处理表名。因此,在包含多个表的连接查询中,选择记录条...

    SQL 优化原则

    我们要做到不但会写SQL,还要做到写出性能优良的SQL,以下为笔者学习、摘录、并汇总部分资料与大家分享! (1) 选择最有效率的表名顺序(只在基于规则的优化器中有效): ORACLE 的解析器按照从右到左的顺序处理FROM...

    高性能建站教程

    本教程旨在深入讲解这些关键知识点,帮助你构建出响应迅速、用户体验优良的网站。 1. **前端优化**:高性能网站的第一步始于前端。这涉及到减少HTTP请求的数量,通过合并CSS和JavaScript文件,使用CDN(内容分发...

    Teradata training material(day4_afternoon.zip)

    这部分可能会详细解析如何写出性能优良的SQL语句。 3. **数据仓库和ETL过程**:Teradata在数据仓库领域有广泛的应用,学员将学习如何设计和实施数据仓库模型,以及如何使用Teradata的工具进行数据提取、转换和加载...

    阿里巴巴Java开发手册(终极版).pdf

    这部分内容涵盖了表结构设计、索引的合理使用以及SQL语句的编写规范等,帮助开发者写出性能优良且稳定的数据库代码。 最后,工程结构部分强调了应用分层的重要性,提倡使用二方库依赖和服务器配置的规范,以确保...

    易语言鑫佑数据库操作类V3.22模块源码

    通过深入学习和实践,开发者能够编写出性能优良且功能完善的数据库应用程序。而“content.txt”文件可能包含了模块的详细使用说明、示例代码或者数据库操作的教程内容,是进一步了解和掌握这个模块的关键资料。

    delphi操作MYSQL数据库(嵌入版)例子

    在这个例子中,我们可能使用的是DBExpress框架,因为它支持多种数据库系统,包括MySQL,并且使用简单,性能优良。 2. **DBExpress框架**: DBExpress是一个轻量级的数据库访问层,它提供了一种跨数据库平台的API,...

    学生信息管理系统代码

    通过这两者的结合,开发者能够构建出一个功能齐全、性能优良的系统,满足学校对学生信息管理的需求。这个项目不仅锻炼了开发者在数据库设计、编程技术上的技能,同时也加深了对软件工程流程的理解,特别是需求分析、...

    基于SpringBoot+MyBatis+Vue的教评管理系统.zip

    1. **虚拟DOM**:Vue使用虚拟DOM技术,当数据变化时,Vue会计算出最小的DOM变更,以提高性能。 2. **指令系统**:Vue提供了一系列内置指令,如v-if、v-for、v-bind、v-on等,用于实现各种常见的DOM操作。 3. **...

    JSP+ MYSQL

    【JSP+MYSQL】是一个经典的Web开发组合,用于构建动态、数据驱动的网站。JSP(JavaServer Pages)是Java平台上的一个技术,...通过深入理解和熟练运用这两项技术,开发者可以构建出功能丰富、性能优良的Web应用程序。

    css界面效果与ssh分页显示

    在IT行业中,SSH和CSS是两个非常重要的概念,它们...在实际项目中,这些技术的结合能够帮助我们构建出功能完善、交互友好、性能优良的Web应用。对于初学者来说,理解并掌握这些知识点,对于提升开发能力具有重要意义。

    mysql+springmvc+ibatis+bootstrap

    【iBatis】是一个SQL映射框架,它允许开发者将SQL语句直接写在配置文件中,与Java代码进行分离,提高了数据库操作的便捷性和可维护性。iBatis与Spring的集成使得在事务管理、对象关系映射等方面更为顺畅,减少了手动...

    SSH框架面试题目及答案

    4. 性能优良,轻量级,支持多种数据库和复杂关系映射。 **二、Hibernate的延迟加载(Lazy Loading)** 1. Hibernate 2和3都支持实体对象和集合的延迟加载。当数据未实际加载到内存中,只有在需要时才加载,节省内存...

    基于python深度学习的聊天机器人源码数据库.docx

    MySQL因其稳定性高、性能优良等特点,在众多数据库系统中脱颖而出,非常适合存储聊天记录和用户信息等数据。 #### 关键技术点分析 - **深度学习算法**:本项目的核心在于其采用的深度学习算法。通过神经网络模型...

    Visual C++程序设计学习笔记

    总的来说,《Visual C++程序设计学习笔记》将带领读者从零基础开始,逐步掌握Visual C++的编程技术,直至能够独立开发出功能完备、性能优良的Windows应用程序。这份笔记不仅是初学者的良师,也是经验丰富的开发者...

Global site tag (gtag.js) - Google Analytics