文档库 最新最全的文档下载
当前位置:文档库 › SQL语句性能优化

SQL语句性能优化

SQL语句性能优化
SQL语句性能优化

SQL

语句性能优化

1、Oracle的From子句表的顺序:记录越多的表放在越前面(左);右边的表为驱动表,驱动表越小,最终扫描的数据越少。

Oracle解析器按照从右向左的顺序处理From子句中的表名,最右的表将被最先处理。如果有3个以上的表连接查询,那就需要选择交叉表(intersection table) 作为基础表,交叉表是指那个被其它表所引用的表。

2、Oracle的where子句表达式的顺序:过滤掉最大数目记录的条件放到where 子句的末尾。

Oracle的执行计划的条件过滤从最后向前进行,过滤数据最多的在最后可以提高数据库的查询速度。

3、Select子句中避免使用‘*’,只返回需要的列名即可

Oracle在解析的过程中会将‘*’一次转换成所有的列名,这个工作是通过查询数据字典完成的,这样将耗费更多的事件;

4、在执行结果等效的情况下,使用Truncate代替Delete;

当删除表中记录时,在通常情况下,回滚段用来存放可以被恢复的信息,如果没有commit事务,oracle会将数据恢复到删除之前的状态。使用truncate时,回滚段不再存放任何可恢复的信息,数据不能被恢复。

5、为了在查询过程中要尽量使用索引,对于like语句避免使用右匹配或者中间匹配的模糊查询;

6、将过滤条件尽可能放到Where子句中,而不是放到Having子句中;

Having子句是用来对分组后的结果进行过滤,限制分组后的查询结果。Having 子句会再检索出所有记录之后才对结果集进行过滤,而且在使用Having子句时一般需要执行排序、统计等操作。执行这些操作时,SQL优化器会进行一些额外的工作,这就需要消耗额外的时间。

7、在SQL语句中,要减少对表的查询,特别是在含有子查询的SQL子句中;

8、使用表的别名可以减少解析的时间并避免引起歧义;

9、使用EXISTS替代IN,用NOT EXISTS替代NOT IN;

10、通常情况下,采用表连接的方式比exists更有效率;

11、当提交一个包含一对多表信息(比如部门表和雇员表)的查询时,避免在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);

12、使用‘>=’替代‘>’,这样DBMS可直接跳到等于的记录上,可能会避免向前的扫描工作;

13、用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, 那就需要返回记录最少的索引列写在最前面.

14、避免在索引列上使用计算,如where语句中的表达式

sal *12 > 2500

应该改为

sal 〉2500/12;

15、避免在索引列上使用IS NULL和IS NOT NULL工作,这样index将不被使用;

16、如果必要,使用函数索引,如对

Upper(name)建立索引;

17、避免在索引列上使用Not,这样将执行全表扫描;

18、如果可能,用union-all替换union

语句:当SQL语句需要UNION两个查询结果集合时,这两个结果集合会以UNION-ALL

的方式被合并, 然后在输出最终结果前进行排序.

如果用UNION ALL替代UNION, 这样排序就不是必要了. 效率就会因此得到提高.

19、避免使用耗费资源的操作:带有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY 的SQL语句会启动SQL引擎,执行耗费资源的排序(SORT)功能. DISTINCT需要一次排序操作, 而其他的至少需要执行两次排序.

20、尽量避免不必要的排序;

21、能够批量查询的情况,不要使用循环语句单次查询,避免IO开销;

22、多使用Commit

语句:在一个事务中,避免大批量修改的,这样可能由于不断扩充回

滚段而影响性能。Commit所释放的资源:

A、回滚段上用于恢复数据的信息。

B、被程序语句获得的锁。

C、redo log buffer中的空间。

D、oracle为管理上诉资源中的内部花费(oracle自身消耗)。

23、在写完一条SQL语句后,使用适当的工具(如Explain plan)检查SQL语句的性能;

24、如果使用IN语句时,IN(a,b,c……..),IN的内容不能超过1000,可以使用变通的方法,将查询内容做个临时表或者分多个in语句实现。

25、连接查询多个表而不是执行多个查询。执行一条语句的效率要高于执行两个语句的效率;正在连接的过程中尽量少使用视图;连接的顺序应该是数据多的表应该先进行连接。

26、使用case表达式而不是执行多个查询。

例如:统计男性作者的数量和女性作者的数量。

Select count(*) from anthors where gender=’M’;

Select count(*) from authors where gender=’F’;

被替换为

Select count(case when gender=’M’then 1 else null end) male_auther,count(case when gender=’F’then 1 else null end) female_auther from authors;

提高查询的效率。

27、在连接查询中,使用完全限定的列别名引用,即我们所说的利用别名。

28、使用start with….connect by

子句进行递归查询时,查询的对象必须是实际存在的,查询的对象不能是使用dblink进行的跨数据库对象。

29、如果想要查询与列表匹配的记录,可以有两种方式,一种是使用OR

关键字,另外一种就是使用IN关键字。但是,在SQL语句中应该使用IN关键字代替OR关键字。因为OR关键字并不会使用索引,因此,使用IN关键字可以提高数据的查询速度。

30、避免使用<>和!=操作符。例如查询教师信息表中工资不为3000的教师记录,查询SQL语句如下:

select teaID,teaName,salary from T_teacher

From T_teacher

Where salary<>30000;

为了提高查询效率,可以把这个查询语句改写成下面这种形式。

Select teaID,teaName,salary

From T_teacher

Where salary<3000 or salary>3000

31、对于一些功能复杂的累活使用存储过程实现优于SQL语句。存储过程运行在服务器端,在运行之前,数据库已经对其进行了变异并提供了相应的优化执行方案,而SQL语句在执行时,数据库需要对其进行语法分析和检查,而且一直SQL语句解析之后是保存在内存中,如果其他操作使用内存,该SQL语句就会被释放,因此它并不是永久的。

32、规范SQL语句书写格式。SQL语句可读性好,势必会降低程序调式的难度。

33、减少访问数据库的次数:

procedure

中有变量时尽量使用绑定变量。

34、使用decode函数减少处理时间:使用decode函数可以避免重复扫描相同记录或重复连接相同的表。

35、删除重复记录:最高效的删除重复记录方法,例如:

Delete from emp e where e.rowin>(select min(x.rowid) from emp x where x.emp_no=e.emp_no);

36、减少对表的查询:在含有子查询的SQL语句中,要特别注意减少对表的查询,例如:

Select tab_name from tables where (tab_name,db_ver)=(select tab_name,db_ver from

tab_columns where version=640);

37、所有脚本建议都是用大写进行编写,因为oracle总是先解析sql语句,把

小写的字母转换成大写的再执行。

38、在代码中进行少用“+”连接字符串,也就是不需要使用左右外连接时尽量少用。

39、使用索引的第一个列。如果索引是建立在多个列上,只有在它的第一个列被where子句已用时,优化器才会使用该索引。

40、用WHERE替代ORDER BY。

Order by子句只在两种严格的条件下使用索引。

A:Order by中所有的列必须包含在相同的索引中并保持在索引中的排列顺序。

B:Order by中所有的列必须定义为非空。

Where子句使用的索引和order by子句中所使用的索引不能并列。

41、避免改变索引列的类型. 当比较不同数据类型的数据时, 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会优先转换数值类型到字符类型。

sql语句(mysql优化)绝对经典

sql语句(mysql优化)绝对经典 误区1:count(1)和count(primary_key) 优于count(*) 很多人为了统计记录条数,就使用count(1) 和count(primary_key) 而不是count(*) ,他们认为这样性能更好,其实这是一个误区。对于有些场景,这样做可能性能会更差,应为数据库对count(*) 计数操作做了一些特别的优化。 误区2:count(column) 和count(*) 是一样的 这个误区甚至在很多的资深工程师或者是DBA 中都普遍存在,很多人都会认为这是理所当然的。实际上,count(column) 和count(*) 是一个完全不一样的操作,所代表的意义也完全不一样。count(column) 是表示结果集中有多少个column字段不为空的记录,count(*) 是表示整个结果集有多少条记录 误区3:select a,b from … 比select a,b,c from …可以让数据库访问更少的数据量 这个误区主要存在于大量的开发人员中,主要原因是对数据库的存储原理不是太了解。实际上,大多数关系型数据库都是按照行(row)的方式存储,而数据存取操作都是以一个固定大小的IO单元(被称作block 或者page)为单位,一般为4KB,8KB… 大多数时候,每个IO单元中存储了多行,每行都是存储了该行的所有字段(lob等特殊类型字段除外)。 所以,我们是取一个字段还是多个字段,实际上数据库在表中需要访问的数据量其实是一样的。当然,也有例外情况,那就是我们的这个查询在索引中就可以完成,也就是说当只取a,b两个字段的时候,不需要回表,而c这个字段不在使用的索引中,需要回表取得其数据。在这样的情况下,二者的IO量会有较大差异。(覆盖索引) 误区4:order by 一定需要排序操作 我们知道索引数据实际上是有序的,如果我们的需要的数据和某个索引的顺序一致,而且我们的查询又通过这个索引来执行,那么数据库一般会省略排序操作,而直接将数据返回,因为数据库知道数据已经满足我们的排序需求了。实际上,利用索引来优化有排序需求的SQL,是一个非常重要的优化手段。延伸阅读:MySQL ORDER BY 的实现分析,MySQL 中GROUP BY 基本实现原理以及MySQL DISTINCT 的基本实现原理。(order by null)

SQL监控及性能优化

SQL 性能监控及SQL 语句优化 性能监控 作为SQL的数据库服务器,我们可以将其比作一个人,而SQL则是他的心脏,管理员就是他的大脑。要监控心脏是否健康首先要看他这个人是否健康。这两者是相辅相成的,少了一方都是不健康的。 数据库服务器的性能监视器 性能监视器 性能工具的介绍 性能监视器是一种简单而功能强大的可视化工具,用于实时收集系统状态并从日志文件中查看性能数据。 使用性能监视器可以: 获得对诊断系统问题和规划系统资源增长有用的性能数据、了解工作负载及其对系统资源的影响、观察工作负载和资源使用情况的变化和趋势,以便计划未来的升级、通过监视结果来测试配置变化、诊断问题并确定需要优化的组件或进程。 现在,可以开始选择这些对象和要监视的计数器了。 https://www.wendangku.net/doc/3d11037633.html, 应用程序性能计数器有关https://www.wendangku.net/doc/3d11037633.html, 应用程序性能计数器的大部分信息最近已被合并到一个题为“改善 .NET 应用程序的性能和伸缩性”的综合文档中。下表描述了一些可用于监视和优化 https://www.wendangku.net/doc/3d11037633.html, 应用程序(包括 Reporting Services)性能的重要计数器。

除了上表中介绍的这些核心监视要素之外,在您试图诊断 https://www.wendangku.net/doc/3d11037633.html, 应用程序具有的特定性能问题时,下表中的性能计数器也可对您有所帮助。

Reporting Services 性能计数器 Reporting Services 包括一组它自己的性能计数器,用于收集有关报告处理和资源消耗方面的信息。可通过 Windows 性能监视器工具中出现的两个对象来监视实例和组件的状态和活动:MSRS 2005 Web Service 和 MSRS 2005 Windows Service 对象。 MSRS 2005 Web Service 性能对象包括一组用来跟踪 Report Server 处理过程的计数器,这些处理过程通常通过在线交互式报告浏览操作而引发。这些计数器在https://www.wendangku.net/doc/3d11037633.html, 停止该 Web 服务后被重设。下表列出了可用于监视 Report Server 性能的计数器,并描述了它们的目的。 性能对象:RS Web Service

SQL2019系统性能优化解决方案共12页文档

SQL Server 系统性能调优解决方案 前言 近几年,医药流通市场经历了激烈的震荡,导致行业逐步成熟和企业的快速变革,差异化经营成为众多医药流通的竞争选择。时空产品在中国医药流通企业的发展过程中得到了广泛且深入应用,大量的客户化开发和定制支撑了企业管理中横向和纵向的变化,很好的适应了企业在发展过程中不断变化的需求。 对于数据库管理系统的使用,很多用户都面临着一个很棘手的问题:系统效率下降。产生效率下降的因素是多方面: 1.硬件问题 2.软件问题 3.实施问题 正因为产生效率下降的因素很多,所以如何去查找原因成为我们首要关注的问题,时空公司也处在积极探索过程中。时空公司在解决一些客户问题的过程中积累了一些方法和思路,归纳总结后呈现给体系内的技术人员,本方案就系统效率调整所必需的基础知识、方法、技巧等几个方面进行阐述,从而让技术人员能够快速定位问题,解决问题,为合作伙伴提供优质,快捷的服务。 索引简介 索引是根据数据库表中一个或多个列的值进行排序的结构。索引提供指针以指向存储在表中指定列的数据值,然后根据指定的排序次序排列这些指针。数据库使用索引的方式与使用书的目录很相似,通过搜索索引找到特定的值,然后跟随指针到达包含该值的行。 索引键:用于创建索引的列。 索引类型 ?聚集索引: 聚集索引基于数据行的键值在表内排序和存储这些数据行。由于数据行按基于聚集索引键的排序次序存储,因此聚集索引对查找行很有效。每个表只能有一个聚集索引,因为数据行本身只能按一个顺序存储。数据行本身构成聚集索引的最低级别(叶子节点)。只有当表包含聚集索引时,表内的数据行才按排序次序存储。如果表没有聚集索引,则其数据行按堆集方式存储。 聚集索引对于那些经常要搜索范围值的列特别有效。使用聚集索引找到包含第一个值的行后,便可以确保包含后续索引值的行在物理相邻。例如:如果应用程序执行的一个查询经常检索某一日期范围内的记录,则使用聚集索引可以迅速找到包含开始日期的行,然后检索表中所有相邻的行,直到到达结束日期。这样有助于提高此类查询的性能。同样,如果对从表中检索的数据进行排序时经常要用到某一列,则可以将该表在该列上聚集(物理排序),避免每次查询该列时都进行排序,从而节省成本。 ?非聚集索引 非聚集索引具有完全独立于数据行的结构。非聚集索引的最低行包含非聚集索引的键值,并且每个键值项都有指针指向包含该键值的数据行。数据行不按基于非聚集键的次序存储。如

Oracle SQL性能优化方法研究

Oracle SQL性能优化方法探讨 Oracle性能优化方法(SQL篇) (1) 1综述 (2) 2表分区的应用 (2) 3访问Table的方式 (3) 4共享SQL语句 (3) 5选择最有效率的表名顺序 (5) 6WHERE子句中的连接顺序. (6) 7SELECT子句中幸免使用’*’ (6) 8减少访问数据库的次数 (6) 9使用DECODE函数来减少处理时刻 (7) 10整合简单,无关联的数据库访问 (8) 11删除重复记录 (8) 12用TRUNCATE替代DELETE (9) 13尽量多使用COMMIT (9) 14计算记录条数 (9) 15用Where子句替换HAVING子句 (9) 16减少对表的查询 (10) 17通过内部函数提高SQL效率 (11)

18使用表的不名(Alias) (12) 19用EXISTS替代IN (12) 20用NOT EXISTS替代NOT IN (13) 21识不低效执行的SQL语句 (13) 22使用TKPROF 工具来查询SQL性能状态 (14) 23用EXPLAIN PLAN 分析SQL语句 (14) 24实时批量的处理 (16)

1综述 ORACLE数据库的性能调整是个重要,却又有难度的话题,如何有效地进行调整,需要通过反反复复的过程。在数据库建立时,就能依照顾用的需要合理设计分配表空间以及存储参数、内存使用初始化参数,对以后的数据库性能有专门大的益处,建立好后,又需要在应用中不断进行应用程序的优化和调整,这需要在大量的实践工作中不断地积存经验,从而更好地进行数据库的调优。 数据库性能调优的方法 ●调整内存 ●调整I/O ●调整资源的争用问题 ●调整操作系统参数 ●调整数据库的设计 ●调整应用程序 本文针对应用程序的调整,来讲明对数据库性能如何进行优化。 2表分区的应用 关于海量数据的表,能够考虑建立分区以提高操作效率。建

SQLServer性能优化工具

SQLServer性能优化工具 数据和工作负荷示例 使用下例说明 SQL Server 性能工具的使用。首先创建下表。 create table testtable (nkey1 int identity, col2 char(300) default 'abc', ckey1 char(1)) 接下来,在这个表中填充 10,000 行测试数据。可以为列 nkey1 中所填充的数据创建非聚集索引。可以为列 ckey1 中的数据创建聚集索引,col2 中的数据仅仅是填充内容,将每一行增加 300 字节。 declare @counter int set @counter = 1 while (@counter <= 2000) begin insert testtable (ckey1) values ('a') insert testtable (ckey1) values ('b') insert testtable (ckey1) values ('c')

insert testtable (ckey1) values ('d') insert testtable (ckey1) values ('e') set @counter = @counter + 1 end 数据库服务器将进行下面的两个查询: select ckey1,col2 from testtable where ckey1 = 'a' select nkey1,col2 from testtable where nkey1 = 5000 Profiler SQL Server Profiler 记录数据库服务器中所发生活动的详细信息。可以配置 Profiler 以便用大量的可配置性能信息监视并记录在 SQL Server 中执行查询的一个或多个用户。可在 Profiler 中记录的性能信息有:I/O 统计信息、CPU 统计信息、锁定请求、T-SQL 和 RPC 统计信息、索引和表扫描、警告和引发的错误、数据库对象的创建/除去、连接/断开、存储过程操作、游标操作等等。有关 SQL Profiler 可记录的全部信息,请在SQL Server Books Online 中搜索字符串“Profiler”。 将 Profiler 信息装载到 .trc 文件中以便用于 Index Tuning Wizard 中 Profiler 和 Index Tuning Wizard 是强大的工具组合,以帮助数

SQL性能优化

近期因工作需要,希望比较全面的总结下SQL SERVER数据库性能优化相关的注意事项,在网上搜索了一下,发现很多文章,有的都列出了上百条,但是仔细看发现,有很多似是而非或者过时(可能对SQL SERVER6.5以前的版本或者ORACLE是适用的)的信息,只好自己根据以前的经验和测试结果进行总结了。 我始终认为,一个系统的性能的提高,不单单是试运行或者维护阶段的性能调优的任务,也不单单是开发阶段的事情,而是在整个软件生命周期都需要注意,进行有效工作才能达到的。所以我希望按照软件生命周期的不同阶段来总结数据库性能优化相关的注意事项。 一、分析阶段 一般来说,在系统分析阶段往往有太多需要关注的地方,系统各种功能性、可用性、可靠性、安全性需求往往吸引了我们大部分的注意力,但是,我们必须注意,性能是很重要的非功能性需求,必须根据系统的特点确定其实时性需求、响应时间的需求、硬件的配置等。最好能有各种需求的量化的指标。 另一方面,在分析阶段应该根据各种需求区分出系统的类型,大的方面,区分是OLTP(联机事务处理系统)和OLAP(联机分析处理系统)。 二、设计阶段 设计阶段可以说是以后系统性能的关键阶段,在这个阶段,有一个关系到以后几乎所有性能调优的过程—数据库设计。 在数据库设计完成后,可以进行初步的索引设计,好的索引设计可以指导编码阶段写出高效率的代码,为整个系统的性能打下良好的基础。 以下是性能要求设计阶段需要注意的: 1、数据库逻辑设计的规范化 数据库逻辑设计的规范化就是我们一般所说的范式,我们可以这样来简单理解范式: 第1规范:没有重复的组或多值的列,这是数据库设计的最低要求。 第2规范: 每个非关键字段必须依赖于主关键字,不能依赖于一个组合式主关键字的某些组成部分。消除部分依赖,大部分情况下,数据库设计都应该达到第二范式。 第3规范: 一个非关键字段不能依赖于另一个非关键字段。消除传递依赖,达到第三范式应该是系统中大部分表的要求,除非一些特殊作用的表。 更高的范式要求这里就不再作介绍了,个人认为,如果全部达到第二范式,大部分达到第三范式,系统会产生较少的列和较多的表,因而减少了数据冗余,也利于性能的提高。 2、合理的冗余 完全按照规范化设计的系统几乎是不可能的,除非系统特别的小,在规范化设计后,有计划地加入冗余是必要的。

MySQL数据库性能(SQL)优化方案

MySQL数据库性能(SQL)优化方案本文探讨了提高MySQL 数据库性能的思路,并从8个方面给出了具体的解决方法。 1、选取最适用的字段属性 MySQL可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快。因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得尽可能小。例如,在定义邮政编码这个字段时,如果将其设置为CHAR(255),显然给数据库增加了不必要的空间,甚至使用VARCHAR这种类型也是多余的,因为CHAR(6)就可以很好的完成任务了。同样的,如果可以的话,我们应该使用MEDIUMINT而不是BIGIN 来定义整型字段。 另外一个提高效率的方法是在可能的情况下,应该尽量把字段设置为NOT NULL,这样在将来执行查询的时候,数据库不用去比较NULL值。 对于某些文本字段,例如“省份”或者“性别”,我们可以将它们定义为ENUM类型。因为在MySQL中,ENUM类型被当作数值型数据来处理,而数值型数据被处理起来的速度要比文本类型快得多。这样,我们又可以提高数据库的性能。 2、使用连接(JOIN)来代替子查询(Sub-Queries) MySQL从4.1开始支持SQL的子查询。这个技术可以使用SELECT语句来创建一个单列的查询结果,然后把这个结果作为过滤条件用在另一个查询中。例如,我们要将客户基本信息表中没有任何订单的客户删除掉,就可以利用子查询先从销售信息表中将所有发出订单的客户ID取出来,然后将结果传递给主查询,如下所示: DELETE FROM customerinfo WHERE CustomerID NOT in (SELECT CustomerID FROM salesinfo )

Oracle_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, 这样程序的性能得到提高,需求

一次TOP_SQL的性能调优经历

1.问题发现 1.1一份AWR报告 今天,收到一份100个并发用户访问下压力测试的AWR报告,并发事务数平均每秒只有6个不到。 在这个26.53分钟间隔的报告里,CPU TIME在整个TOP 事件中最突出 占了近97.6%,在8个CPU系统中,数据库给CPU造成的压力为: (5740/(26.53*60*8)*100%=45.07%,这么小的压力下,CPU就能冲得这么高,说明

系统中肯定是有问题的。下面转向TOP SQL去确认下造成资源争用最明显的SQL语句。 1.2TOP SQL 1.2.1SQL ordered by Elapsed Time 1.2.2SQL ordered by CPU Time

1.2.3SQL ordered by Gets 1.3问题发现 对一个OLTP系统来说,每一个语句的执行,都是要将其消耗的资源降到最低,这跟 OLAP系统是有差别的。对于后者来说,它需要的是短的时间返回结果,不管中间你会拿多大的成本做代价。 从上面反映的问题来看,我们的性能,无疑就是葬送在了SQL_ID为4841ajtgh43qy、1hwqh7kvxn6yg、g295mubwupf52和anyty5rts5tzf这四个语句上面,下面将对这四个SQL语句一 一做出分析,并给出相应的调优建议。

2.SQL_ID为4841ajtgh43qy的语句 2.1调整前 2.1.1语句 SELECT * FROM (SELECT TT.*, ROWNUM AS ROWNO FROM (select to_char(c.cust_id), c.password from CUST_CERTIFICATION c where c.cust_id = :CUST_ID) TT WHERE ROWNUM <= 10) TABLE_ALIAS where TABLE_ALIAS.rowno > 0 ; 2.1.2解释计划 又见全表扫

高性能SQL优化总结

SQL 高性能查询优化语句,一些经验总结 1.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: select id from t where num is null; 可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:select id from t where num = 0; 2.应尽量避免在 where 子句中使用!=或$amp; 3.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如: select id from t where num=10 or num=20; 可以这样查询: select id from t where num=10 union all select id from t where num=20; 4.in 和 not in 也要慎用,因为IN会使系统无法使用索引,而只能直接搜索表中的数据。如: select id from t where num in(1,2,3) 对于连续的数值,能用 between 就不要用 in 了:

select id from t where num between 1 and 3; 5.尽量避免在索引过的字符数据中,使用非打头字母搜索。这也使得引擎无法利用索引。 见如下例子: SELECT * FROM T1 WHERE NAME LIKE ‘%L%’; SELECT * FROM T1 WHERE SUBSTING(NAME,2,1)=’L’; SELECT * FROM T1 WHERE NAME LIKE ‘L%’; --第三个查询能够使用索引来加快操作 即使NAME字段建有索引,前两个查询依然无法利用索引完成加快操作,引擎不得不对全表所有数据逐条操作来完成任务。而第三个查询能够使用索引来加快操作。 6.必要时强制查询优化器使用某个索引,如在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描: select id from t where num=@num; 可以改为强制查询使用索引:

数据库性能优化之SQL语句优化

数据库性能优化之SQL语句优化一、问题的提出 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,但是如果将应用系统提交实际应用后,随着数据库中数据的增加,系统的响应速度就成为目前系统需要解决的最主要的问题之一。系统优化中一个很重要的方面就是SQL语句的优化。对于海量数据,劣质SQL语句和优质SQL语句之间的速度差别可以达到上百倍,可见对于一个系统不是简单地能实现其功能就可,而是要写出高质量的SQL语句,提高系统的可用性。 在多数情况下,Oracle使用索引来更快地遍历表,优化器主要根据定义的索引来提高性能。但是,如果在SQL语句的where子句中写的SQL代码不合理,就会造成优化器删去索引而使用全表扫描,一般就这种SQL语句就是所谓的劣质SQL语句。在编写SQL语句时我们应清楚优化器根据何种原则来删除索引,这有助于写出高性能的SQL语句。 二、SQL语句编写注意问题 下面就某些SQL语句的where子句编写中需要注意的问题作详细介绍。在这些where子句中,即使某些列存在索引,但是由于编写了劣质的SQL,系统在运行该SQL语句时也不能使用该索引,而同样使用全表扫描,这就造成了响应速度的极大降低。

1. 操作符优化 (a) IN 操作符 用IN写出来的SQL的优点是比较容易写及清晰易懂,这比较适合现代软件开发的风格。但是用IN的SQL性能总是比较低的,从Oracle执行的步骤来分析用IN的SQL与不用IN的SQL有以下区别: ORACLE试图将其转换成多个表的连接,如果转换不成功则先执行IN里面的子查询,再查询外层的表记录,如果转换成功则直接采用多个表的连接方式查询。由此可见用IN的SQL至少多了一个转换的过程。一般的SQL都可以转换成功,但对于含有分组统计等方面的SQL就不能转换了。 推荐方案:在业务密集的SQL当中尽量不采用IN操作符,用EXISTS 方案代替。 (b) NOT IN操作符 此操作是强列不推荐使用的,因为它不能应用表的索引。 推荐方案:用NOT EXISTS 方案代替 (c) IS NULL 或IS NOT NULL操作(判断字段是否为空) 判断字段是否为空一般是不会应用索引的,因为索引是不索引空值的。不能用null作索引,任何包含null值的列都将不会被包含在索引中。即使索引有多列这样的情况下,只要这些列中有一列含有null,该列就会从索引中排除。也就是

SQL%20查询语句优化

我们要做到不但会写SQL,还要做到写出性能优良的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种资源中的内部花费

PLSQL程序优化和性能分析方法要点

1. 前言 1.1 目的 性能测试是测试中比较重要的工作,性能测试应分为压力的测试和性能的测试,其中性能问题中绝大部分都是由于程序编写的不合理、不规范造成的。本文档说明了程序中常见的不优化的脚本编写,导致的性能问题,并且在也描述了怎样去跟踪和解决程序上的性能问题的方法。 在最后一章里面描述了做一个白盒测试工具测试性能问题的设计思想。 1.2 文档说明 本文档只说明PLSQL编写的优化问题,不包括ORACLE本身的性能优化(内存SGA、系统参数、表空间等)、操作系统的性能问题和硬件的性能问题。对于PLSQL程序优化方面的内容有很多,本文档列出在我们实际工作中一些常见的情况。本文档难免有不正确的地方,也需要大家给予指正。 本文档举例说明的问题语句不是实际程序中真正存在的,只是让大家能看起来更容易理解,但这些语句也不代表在我们程序中其他部分语句不存在这些问题。 举例说明中的语句采用的是社保核心平台的数据字典,在举例描述中没有标明表名和字段名的含义,还需单独参考。 1.3 词汇表 1.4 参考资料

2. PLSQL程序优化原则 2.1 导致性能问题的内在原因 导致系统性能出现问题从系统底层分析也就是如下几个原因: ●CPU占用率过高,资源争用导致等待 ●内存使用率过高,内存不足需要磁盘虚拟内存 ●IO占用率过高,磁盘访问需要等待 2.2 PLSQL优化的核心思想 PLSQL优化实际上就是避免出现“导致性能问题的内在原因”,实际上编写程序,以及性能问题跟踪应该本着这个核心思想去考虑和解决问题。 ●PLSQL程序占用CPU的情况 ?系统解析SQL语句执行,会消耗CPU的使用 ?运算(计算)会消耗CPU的使用 ●PLSQL程序占用内存的情况 ?读写数据都需要访问内存 ?内存不足时,也会使用磁盘 ●PLSQL程序增大IO的情况 ?读写数据都需要访问磁盘IO ?读取的数据越多,IO就越大 大家都知道CPU现在都很高,计算速度非常快;访问内存的速度也很快;但磁盘的访问相对前两个相比速度就差的非常大了,因此PLSQL性能优化的重点也就是减少IO的瓶颈,换句话说就是尽量减少IO的访问。 性能的优先级CPU->内存->IO,影响性能的因素依次递增。根据上面的分析,PLSQL优化的核心思想为: 1.避免过多复杂的SQL脚本,减少系统的解析过程 2.避免过多的无用的计算,例如:死循环 3.避免浪费内存空间没有必要的SQL脚本,导致内存不足 4.内存中计算和访问速度很快 5.尽可能的减少磁盘的访问的数据量,该原则是PLSQL优化中重要思想。 6.尽可能的减少磁盘的访问的次数,该原则是PLSQL优化中重要思想。 下面的章节具体介绍常见影响性能的SQL语句情况。 2.3 ORACLE优化器 ORACLE的优化器:

SQL优化的几个方面

SQL优化的几个方面 sql数据库优化非常重要,如果sql数据库优化的不好,不仅会增加客户端和服务器端程序的编程和维护的难度,而且还会影响系统实际运行的性能。 那我们可以从哪些方面来进行sql数据库优化呢? 一:就是合理的数据库的设计。 当前我们使用最多的就是关系型数据库,关系数据库设计是对数据进行组织化和结构化的过程,核心问题是关系模型的设计。对于数据库规模较小的情况,我们可以比较轻松的处理数据库中的表结构。然而,随着项目规模的不断增长,相应的数据库也变得更加复杂,关系模型表结构更为庞杂,这时我们往往会发现我们写出来的SQL语句的是很笨拙并且效率低下的。更糟糕的是,由于表结构定义的不合理,会导致在更新数据时造成数据的不完整。因此数据库的规范化流程尤为重要,它可以以指导我们更好的设计数据库的表结构,减少冗余的数据,借此可以提高数据库的存储效率,数据完整性和可扩展性。 那怎么才算是规范化的设计流程:规范化设计的过程就是按不同的范式,将一个二维表不断地分解成多个二维表并建立表之间的关联,最终达到一个表只描述一个实体或者实体间的一种联系的目标。目前遵循的主要范式包括1

NF、2 NF、3 NF、BCNF、4NF和5NF等几种;在工程中3NF、BCNF应用得最广泛,推荐采用3 NF作为标准。规范化设计的优点包括可有效地消除数据冗余,理顺数据的从属关系,保持数据库的完整性,增强数据库的稳定性、伸缩性、适应性。通常认为规范化设计存在的主要问题是增加了查询时的连接库表运算,导致计算机时间、空间、系统及运行效率的损失。在大多数情况下,这一问题可通过良好的索引设计等方法得到解决。数据库设计中关键的步骤就是要确保数据正确地分布到数据库的表中。比如说,一个客户的地址信息不应该被存储在不同的表中,因为这里的客户地址是雇员的一个属性。如果存在过多的冗余数据,这就意味着要占用了更多的物理空间,同时也对数据的维护和一致性检查带来了问题,当这个客户的地址发生变化时,冗余数据会导致对多个表的更新动作,如果有一个表不幸被忽略了,那么就可能导致数据的不一致性。 二:查询的优化 如何让你写的SQL语句跑的更快呢?影响我们代码速度的都有哪些可能性呢?不恰当的索引设计、不充份的连接条件和不可优化的where子句都有可能造成速度的下降。 首先来看看索引的建立。微软的sql server提供了两种索引:聚集索引(clustered index,也称聚类索引、簇集索引)和非聚集索引(nonclustered

相关文档