oracle效率
- 格式:doc
- 大小:41.50 KB
- 文档页数:8
oracle性能参数说明Oracle数据库是一款功能强大的关系型数据库管理系统 (RDBMS),它提供了许多性能参数来优化数据库的性能。
这些参数允许DBA (数据库管理员)根据数据库的特定需求进行调整,并对数据库的资源使用、查询执行、并发性等方面进行优化。
下面将详细介绍一些常用的Oracle性能参数及其说明。
1.SGA_TARGET和SGA_MAX_SIZE:SGA (System Global Area) 是Oracle数据库使用的一块内存区域,用于缓存数据文件和索引的副本。
SGA_TARGET参数定义了SGA的总大小,而SGA_MAX_SIZE参数定义了SGA的最大大小。
这两个参数可以根据数据库的需求进行调整,以平衡内存的使用和数据库性能。
2.PGA_AGGREGATE_TARGET:PGA (Program Global Area) 是用于存储单个用户进程或排序操作的内存区域。
PGA_AGGREGATE_TARGET参数定义了整个数据库实例的PGA大小。
通过适当调整该参数的值,可以提高多个用户进程的性能。
3.DB_CACHE_SIZE:DB_CACHE_SIZE参数定义了数据缓存区的大小,用于缓存数据文件中的数据块。
它的大小应根据数据库的访问模式和大小进行调整,以提高查询性能和减少磁盘I/O。
4.SHARED_POOL_SIZE:SHARED_POOL_SIZE参数定义了共享池的大小,用于存储共享SQL和PL/SQL代码的执行计划,以及共享游标和会话信息等。
适当调整该参数可以提高SQL查询的性能和共享的效率。
5.LOG_BUFFER:LOG_BUFFER参数定义了重做日志缓冲区的大小,用于暂存数据库的修改操作。
适当增大该参数的值可以减少重做日志文件的频繁切换,提高数据库的写操作性能。
6.PARALLEL_MAX_SERVERS和PARALLEL_THREADS_PER_CPU:PARALLEL_MAX_SERVERS参数定义了并行执行的最大服务器进程数,而PARALLEL_THREADS_PER_CPU参数定义了每个CPU核心的并行线程数。
千里之行,始于足下。
oracle优化方法总结Oracle优化是提高数据库性能和响应能力的重要步骤。
本文总结了一些常见的Oracle优化方法。
1. 使用索引:索引是提高查询性能的主要方法。
通过在表中创建适当的索引,可以加快查询速度,并减少数据访问的开销。
但是要注意不要过度使用索引,因为过多的索引会增加写操作的开销。
2. 优化查询语句:查询语句的效率直接影响数据库的性能。
可以通过合理地编写查询语句来提高性能。
例如,使用JOIN来替代子查询,尽量避免使用通配符查询,使用LIMIT来限制结果集的大小等。
3. 优化表结构:表的设计和结构对数据库的性能也有很大的影响。
合理的表设计可以减少数据冗余和不必要的数据存储,提高查询速度。
例如,适当地使用主键、外键和约束,避免过多的数据类型和字段等。
4. 优化数据库参数设置:Oracle有很多参数可以用来调整数据库的性能。
根据具体的应用场景和需求,可以根据情况调整参数的值。
例如,调整SGA和PGA的大小,设置合适的缓冲区大小,调整日志写入方式等。
5. 使用分区表:当表的数据量很大时,可以考虑将表分成多个分区。
分区表可以加速查询和维护操作,提高数据库的性能。
可以按照时间、地域、业务等来进行分区。
6. 优化存储管理:Oracle提供了多种存储管理选项,如表空间和数据文件管理。
合理地分配存储空间和管理数据文件可以提高数据库的性能。
例如,定期清理无用的数据文件,使用自动扩展表空间等。
第1页/共2页锲而不舍,金石可镂。
7. 数据压缩:对于大量重复数据或者冷数据,可以考虑使用Oracle的数据压缩功能。
数据压缩可以减少磁盘空间的使用,提高IO性能。
8. 使用并行处理:对于大型计算或者批处理任务,可以考虑使用Oracle的并行处理功能。
并行处理可以将任务分成多个子任务,并行执行,提高处理能力和效率。
9. 数据库分区:对于大型数据库,可以考虑将数据库分成多个独立的分区。
数据库分区可以提高数据的并行处理能力,减少锁竞争和冲突,提高数据库的性能。
千里之行,始于足下。
oracle优化方案Oracle优化方案Oracle数据库是当今企业界最受欢迎的关系型数据库管理系统之一。
但是,随着数据量的不断增加和业务需求的不断增长,数据库的性能问题也会渐渐变得突出。
因此,对Oracle数据库进行优化是提高系统性能和运行效率的关键。
本文将介绍几个常见的Oracle数据库优化方案,挂念您更好地管理和优化您的数据库环境。
1. 索引优化索引是提高查询性能的关键。
可以通过以下几个方面对索引进行优化:(1)合理选择索引类型:依据查询的特点和数据分布选择合适的索引类型,如B-tree索引、位图索引等。
(2)避开过多的索引:过多的索引会增加数据插入、更新和删除的成本,并降低查询性能。
只保留必要的索引,可以有效提高性能。
(3)定期重建和重新组织索引:定期重建和重新组织索引可以提高索引的查询效率,削减碎片和冗余。
2. SQL优化SQL语句是Oracle数据库的核心,对SQL进行优化可以显著提高数据库的性能。
以下是一些SQL优化的建议:第1页/共3页锲而不舍,金石可镂。
(1)优化查询语句:避开使用不必要的子查询,尽量使用连接查询代替子查询,削减查询次数。
同时,避开使用全表扫描,可以通过创建合适的索引来提高查询效率。
(2)避开使用不必要的OR运算符:OR运算符的查询效率较低,应尽量避开使用。
可以通过使用UNION或UNION ALL运算符代替OR运算符来提高性能。
(3)避开使用ORDER BY和GROUP BY子句:ORDER BY和GROUP BY子句会造成排序和分组操作,对于大数据集来说是格外耗时的。
假如可能,可以考虑使用其他方式来实现相同的功能。
3. 系统资源优化合理配置和管理系统资源是确保数据库运行稳定和高效的重要因素。
以下是一些建议:(1)合理安排内存:依据系统和数据库的实际需求,合理安排内存资源。
调整SGA(System Global Area)区域的大小,确保适当的内存安排给缓冲池和共享池。
oracle分区技术提⾼查询效率概述:当表中的数据量不断增⼤,查询数据的速度就会变慢,应⽤程序的性能就会下降,这时就应该考虑对表进⾏分区。
表进⾏分区后,逻辑上表仍然是⼀张完整的表,只是将表中的数据在物理上存放到多个表空间(物理⽂件上),这样查询数据时,不⾄于每次都扫描整张表。
下⾯介绍如何使⽤分区增加查询效率range分区:就是区域分区CREATE TABLE SALE(PRODUCT_ID VARCHAR2(5),SALE_COUNT NUMBER(10,2))PARTITION BY RANGE (SALE_COUNT)(PARTITION P1 VALUES LESS THAN (1000) TABLESPACE CUS_TS01,PARTITION P2 VALUES LESS THAN (2000) TABLESPACE CUS_TS02)查看分区语法: select * from user_tab_partitions; --查询所有分区情况,可以接条件where table_name='sale'查看分区表结构 select * from sale partition(p1); --查询某表的某⼀分区数据分区后,新增数据的SALE_COUNT字段如果⼩于1000就存储到P1分区中,如果1000到2000存储到P2分区中。
但是这时如果我们新增的⼀条数据的SALE_COUNT字段值⼤于2000,将⽆法存储到表中。
我们可以扩展分区,语法如下: alter table sale add partition p4 values less than(maxvalue); --⼤于2000的都会存到此分区中,当然也可以增加更多的分区同时可以删除分区,语法如下: alter table sale drop partition p4; --注意:删除分区会把分区内已有的数据同时删除但还存在⼀个问题,如果现在update分区p1中的SALE_COUNT值为1500,是不会成功的,需要在update前增加以下语句: alter table sale enable row movement; --使其row能移动这样再update就可以成功了分区索引分区之后虽然可以提⾼查询的效率,但也仅仅是提⾼了数据的范围,所以我们在有必要的情况下,需要建⽴分区索引,从⽽进⼀步提⾼效率。
千里之行,始于足下。
Oracle数据库性能优化分析Oracle数据库性能优化分析是指对Oracle数据库进行综合性能分析和优化的过程。
通过分析数据库的运行状况、识别潜在的性能瓶颈、确定解决方案并实施优化措施,可以提高数据库的性能和效率。
以下是Oracle数据库性能优化分析的一般步骤:1. 收集性能数据:通过Oracle的性能监控工具,如AWR报告、统计信息收集等,收集数据库的性能数据,包括CPU利用率、I/O响应时间、锁定情况等。
2. 确定性能瓶颈:通过分析性能数据,确定数据库中存在的性能瓶颈,如高CPU使用率、高IO等待、长时间的锁等待等。
3. 优化SQL语句:分析执行频次较高的SQL语句,通过重写SQL语句、调整索引和统计信息等方式,优化SQL语句的执行计划,减少IO开销和CPU消耗。
4. 优化数据库结构:根据应用的需求和查询模式,调整表结构、分区策略、索引设计等,以提高查询性能和数据访问效率。
5. 优化数据库配置参数:调整数据库的配置参数,包括缓冲区大小、日志大小、并发连接数等,以最大限度地利用硬件资源,提高数据库的吞吐量和响应时间。
6. 确保数据完整性和一致性:通过使用合适的约束和触发器,确保数据的完整性和一致性,防止数据错误和冲突对性能造成负面影响。
第1页/共2页锲而不舍,金石可镂。
7. 监控和调优:定期监控数据库的性能指标,如响应时间、吞吐量等,及时识别和解决潜在的性能问题,保持数据库的高可用性和性能稳定性。
需要注意的是,性能优化是一个综合性的工作,需要结合具体的应用场景和需求来进行分析和优化,没有一种通用的解决方案,需要根据实际情况进行定制化的优化措施。
同时,性能优化是一个持续改进的过程,需要定期评估数据库的性能状况,并根据需求进行调整和优化。
常见Oracle数据库优化策略与方法
Oracle数据库优化是提高数据库性能的关键步骤,可以采取多种策略。
以下是一些常见的Oracle数据库优化策略:
1.硬件优化:这是最基本的优化方式。
通过升级硬件,比如增加RAM、使用
更快的磁盘、使用更强大的CPU等,可以极大地提升Oracle数据库的性能。
2.网络优化:通过优化网络连接,减少网络延迟,可以提高远程查询的效率。
3.查询优化:对SQL查询进行优化,使其更快地执行。
这包括使用更有效的
查询计划,减少全表扫描,以及使用索引等。
4.表分区:对大表进行分区可以提高查询效率。
分区可以将一个大表分成多
个小表,每个小表可以单独存储和查询。
5.数据库参数优化:调整Oracle数据库的参数设置,使其适应工作负载,可
以提高性能。
例如,调整内存分配,可以提升缓存性能。
6.数据库设计优化:例如,规范化可以减少数据冗余,而反规范化则可以提
升查询性能。
7.索引优化:创建和维护索引是提高查询性能的重要手段。
但过多的索引可
能会降低写操作的性能,因此需要权衡。
8.并行处理:对于大型查询和批量操作,可以使用并行处理来提高性能。
9.日志文件优化:适当调整日志文件的配置,可以提高恢复速度和性能。
10.监控和调优:使用Oracle提供的工具和技术监控数据库性能,定期进行性
能检查和调优。
请注意,这些策略并非一成不变,需要根据实际情况进行调整。
在进行优化时,务必先备份数据和配置,以防万一。
instr和like的效率比较测试环境oracle10g,tcurrentbilllog表总数有近200万条instr(‘源字符串’,’查询字符串’)>0 相当于‘源字符串’ like ’%查询字符串%’ =trueinstr(‘源字符串’,’查询字符串’)=0 相当于‘源字符串’ like ’%查询字符串%’ =false1.%a%方式:select * from pub_yh_bm t where instr(t.chr_bmdm,'2')>0等份于:select * from pub_yh_bm t where t.chr_bmdm like '%2%'2.%a方式:select * from pub_yh_bm twhere instr(t.chr_bmdm,'110101')=length(t.chr_bmdm)-length('110101')+1等份于:select * from pub_yh_bm t where t.chr_bmdm like '%110101'3.a%方式:select * from pub_yh_bm t where instr(t.chr_bmdm,'11010101')=1等份于:select * from pub_yh_bm t where t.chr_bmdm like '11010101%'●全表查询select*from tcurrentbilllog t where instr(t.callerno,'0301')>0;用时:0.188秒解释计划SELECT STATEMENT, GOAL = ALL_ROWS 耗费=4187 基数=30833 字节=6659928TABLE ACCESS FULL 对象所有者=ICD 对象名称=TCURRENTBILLLOG 耗费=4187 基数=30833 字节=6659928select *from tcurrentbilllog t where t.callerno like'%0301%';用时:0.266秒解释计划SELECT STATEMENT, GOAL = ALL_ROWS 耗费=4182 基数=30833 字节=6659928TABLE ACCESS FULL 对象所有者=ICD 对象名称=TCURRENTBILLLOG 耗费=4182 基数=30833 字节=6659928结果:instr查询用时少,但解释计划中耗费高一些。
ORACLE数据库多表关联查询效率问题解决⽅案最近在做项⽬中遇到多表关联查询排序的效率问题(5张以上40W+数据的表),查询⼀次⼤概要20多秒,经过⼀番苦思冥想,处理⽅案如下: 1、软件设计初期,需要⼀对⼀关联的表应该设计在⼀张⼤表⾥,这样虽然字段多些,但是对于查询的速度提升是⾮常明显的,特别是在排序的情况下。
2、我们在关联的时候可能需要排序的表只是其中的⼀张或者两张,我们可以先针对这两张需要排序的表先查询排序,然后再⽤这两个表查询的结果关联其他表。
代码如下:1SELECT*FROM (2SELECT*FROM M_RK_JBXX A3LEFT JOIN M_RK_ZFGX B ON A.RKID = B.RKID4LEFT JOIN(SELECT*5FROM M_DZ_MP D6LEFT JOIN M_DZ_LD E ON D.LDID = E.LDID7ORDER BY E.XC, E.PXH, D.PXH)DD ON B.MPID = DD.MPID8LEFT JOIN M_DZ_WGGL F ON DD.WGID = F.WGID9LEFT JOIN M_RK_HJXXZH C ON C.MPID = DD.MPID10 )后来我在需要分页的环境下,⽤rownum来进⾏分页,发现按照上⾯的排序的顺序就被打乱了。
在⽹上找了很多资料也看了很多博客,也没找到解决⽅案。
所以上⾯的代码的适⽤性就很局限了(不分页的情况下)。
但是我需要⾼效率的分页怎么办呢?rownum满⾜不了我呀。
后来我⼜找到了⼀个函数ROW_NUMBER() OVER(ORDER BY column) ,通过该函数可以极⼤的提⾼查询的效率。
使⽤的⽅式为1SELECT*2FROM (SELECT ROW_NUMBER() OVER(ORDER BY A.PXH, B.PXH) NUM,3 A.*,B.*4FROM TAB1 A5LEFT JOIN TAB2 B6ON A.T2= B.ID7 )8WHERE NUM BETWEEN1AND20通过这种⽅式我的查询速度提⾼了将近10倍,当然我的实际环境⽐这段代码要⿇烦很多。
oracle使⽤withas提⾼查询效率经常在开发过程中会⽤到视图或组合查询的情况,但由于涉及表数据经常达到千万级别的笛卡尔积,⽽且⼀段查询时会反复调⽤,但结果输出往往不需要那么多,可以使⽤with将过滤或处理后的结果先缓存到临时表(此处原理不太清楚,仅代表我的理解),可以⼤⼤提⾼查询效率另外,WMSYS.WM_CONCAT 这个函数可以将查询结果某列多⾏拼接成⼀个结果,⾮常实⽤⽰例:/*查询当前EOMS流程组及组织架构信息create by Gemini.Liu2014-01-07*/--create or replace view v_getcurrent_workflow as--组信息with group_info as(select gp1.group_intid,gp1.group_id,gp1.group_name,gp1.group_fullname,decode(gp1.group_type,3,gp1.group_fullname,2,gp1.group_fullname,gp2.group_fullname) arch,decode(gp1.group_type,3,gp1.group_id,2,gp1.group_id,gp2.group_id) archidfrom ultraprocess_sysgroup gp1,ultraprocess_sysgroup gp2where 1=1and gp1.group_parentid=gp2.group_idand (gp2.group_type = 3 or gp2.group_type = 2)),--组成员group_user as(select WMSYS.WM_CONCAT(er_fullname) person,WMSYS.WM_CONCAT(er_loginname) personid,us2.group_intid from ultraprocess_sysuser us1,ultraprocess_sysgroup us2,ultraprocess_sysgroupuser us3 where 1=1and er_id=us3.mgroup_useridand us2.group_id=us3.mgroup_groupidgroup by us2.group_intid),--映射信息dp_map as(select hj.groupid,hj.processbaseschema from wf_app_dealprocess hjwhere 1=1and hj.groupid is not nulland hj.processbaseschema is not nulland hj.edprocessaction<> 19group by groupid,processbaseschema)/*--⼯单信息,form_info as(select info.basesn,info.baseschema,info.basename,info.basestatus,info.baseid,hj.group_x,hj.groupid,hj.flagactive from wf_app_base_infor info,wf_app_dealprocess hjwhere 1=1and info.baseid=hj.processbaseidand info.baseschema = hj.processbaseschemaand info.basestatus <> '已作废'and hj.edprocessaction<> 19)*/--展现信息select dp_map.processbaseschema ⼯单类别,group_info.group_intid 组ID,group_info.group_name 组名,group_user.person 组成员,group_user.personid 组成员登录名,group_info.arch 所属部门,group_info.archid 所属部门IDfrom dp_map,group_info,group_userwhere 1=1and dp_map.groupid = group_info.group_intidand group_user.group_intid = group_info.group_intid。
Oracle优化SQL语句,提高效率我们都了解索引是相关表概念部分,主要是提高检索数据的相关效率,当Oracle使用了较为复杂的自平衡B-tree结构时。
我们一般是通过索引查询数据比全表扫描要快。
当 Oracle找出执行查询和Update语句的最好路径时, Oracle 优化将使用索引。
同样在联结多个表时使用索引也能够提高效率。
另一个使用索引的好处是,他提供了主键(primary key)的唯一性验证。
那些LONG或LONG RAW数据类型, 您能够索引几乎任何的列。
通常, 在大型表中使用索引特别有效. 当然,您也会发现, 在扫描小表时,使用索引同样能提高效率。
虽然使用索引能得到查询效率的提高,但是我们也必须注意到他的代价。
索引需要空间来存储,也需要定期维护, 每当有记录在表中增减或索引列被修改时, 索引本身也会被修改。
这意味着每条记录的INSERT,DELETE , UPDATE 将为此多付出4、 5次的磁盘I/O 。
因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢。
定期的重构索引是有必要的:ALTER INDEX REBUILD1.用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);2.SQL语句用大写的;因为Oracle总是先解析SQL语句,把小写的字母转换成大写的再执行。
千里之行,始于足下。
Oracle的性能优化
Oracle的性能优化是提高数据库系统性能和响应速度的关键步骤,可以通
过如下几个方面进行优化:
1. 数据库设计和规范化:合理的数据库设计和良好的规范化可以减少数据冗余,提高查询效率,避免数据冲突和不一致。
2. 索引优化:在频繁查询的字段上创建适当的索引,可以加快查询速度。
但是,索引不宜过多,因为它们会增加数据修改和插入的时间。
3. 查询优化:优化查询语句的执行计划,使用正确的连接方法(如内连接、外连接),避免全表扫描。
4. 硬件升级:增加内存、硬盘和处理器等硬件资源,可以显著提高
Oracle数据库的性能。
5. 优化配置参数:根据数据库的特点和应用的需求,调整数据库的配置参数,例如SGA大小、PGA大小、日志文件大小等,以提高性能。
6. 数据库优化:使用合适的数据库特性,如分区表、分区索引、物化视图等,优化数据库的存储和查询效率。
7. 监控和调优:持续监控数据库的性能指标,如CPU利用率、内存使用率、磁盘IO等,并及时进行适当的调优操作。
第1页/共2页
锲而不舍,金石可镂。
总体来说,Oracle的性能优化需要综合考虑数据库设计、硬件配置、查询优化和系统监控等多个方面,通过不断的调整和优化,提高数据库的性能和响应速度。
优化sql语句提高oracle执行效率
1.尽可能高效:采用最有效的查询方式、避免使用不必要的查询语句、提高检索速度而非数据量。
2.避免使用子查询:尽量不使用子查询,把子查询换成联合查询或者
通过多表连接更新数据。
3.避免重复读取:尽量从数据库中读取一次数据,不要读取多次相同
的数据,避免多次查询,提高数据库的查询效率。
4.避免使用NOTIN和NOTEXISTS:尽量不用NOTIN和NOTEXISTS查询
语句,因为这种查询方式比较耗时,可以把NOTIN换成LEFTJOIN不为空
即可。
5.避免使用OR:尽量不用OR,用AND替代OR,AND通常比OR更有效。
6.避免使用模糊查询:尽量不用模糊查询,模糊查询效率较低,可以
用相似查询替代模糊查询。
7.合并多个表:如果有多个表,尽量合并这些表,以便减少查询次数。
8. 使用索引: 设置索引来提高查询速度,尽可能在 Where、Group by、Having、Order by等关键字中使用索引。
9. 优化sql语句顺序: 尽可能把WHERE条件的语句写在前面,以便
优先查询出少量的数据来,提高查询效率;把ORDER BY语句写在最后,
以便能有效地利用索引。
10.选择可用的查询方法:使用最适合的查询方法,选择适当的SELECT语句、JOIN语句和UNION语句,以使SQL语句更快地返回结果。
11. 避免使用Distinct: Distinct能会导致查询效率降低,尽量避免使用Distinct。
Oracle中SQL语句执⾏效率的查找与解决⼀、识别占⽤资源较多的语句的⽅法(4种⽅法) 1.测试组和最终⽤户反馈的与反应缓慢有关的问题。
2.利⽤V_$SQLAREA视图提供了执⾏的细节。
(执⾏、读取磁盘和读取缓冲区的次数) • 数据列 EXECUTIONS:执⾏次数 DISK_READS:读盘次数 COMMAND_TYPE:命令类型(3:select,2:insert;6:update;7delete;47:pl/sql程序单元) OPTIMIZER_MODE:优化⽅式 SQL_TEXT:Sql语句 SHARABLE_MEM:占⽤shared pool的内存多少 BUFFER_GETS:读取缓冲区的次数 • ⽤途 1、帮忙找出性能较差的SQL语句 2、帮忙找出最⾼频率的SQL 3、帮忙分析是否需要索引或改善联接 监控当前Oracle的session,如出现时钟的标志,表⽰此进程中的sql运⾏时间较长。
4. Trace⼯具: a)查看数据库服务的初始参数:timed_statistics、user_dump_dest和max_dump_file_size b)Step 1: alter session set sql_trace=true c)Step 2: run sql; d)Step 3: alter session set sql_trace=false e)Step 4:使⽤ “TKPROF”转换跟踪⽂件 f)Parse,解析数量⼤通常表明需要增加数据库服务器的共享池⼤⼩, query或current提取数量⼤表明如果没有索引,语句可能会运⾏得更有效, disk提取数量表明索引有可能改进性能, library cache中多于⼀次的错过表明需要⼀个更⼤的共享池⼤⼩ ⼆、如何管理语句处理和选项 •基于成本(Cost Based) 和基于规则(Rule Based) 两种优化器,简称为CBO 和RBO •Optimizer Mode参数值: Choose:如果存在访问过的任何表的统计数据,则使⽤基于成本的Optimizer,⽬标是获得最优的通 过量。
ORACLE数据库变得非常慢解决方案一例最近在为一个项目做数据库优化,发现ORACLE数据库运行得特别慢,简直让人头大。
今天就来给大家分享一下我是如何一步步解决这个问题的,希望对你们有所帮助。
事情是这样的,那天老板突然过来,一脸焦虑地说:“小王,你看看这个数据库,查询速度怎么这么慢?客户都投诉了!”我二话不说,立刻开始分析原因。
我打开了数据库的监控工具,发现CPU和内存的使用率都很高,看来是数据库的压力确实很大。
然后,我开始查看慢查询日志,发现了很多执行时间很长的SQL语句。
这时,我意识到,问题的根源可能就在这些SQL语句上。
一、分析SQL语句1.对执行时间长的SQL语句进行优化。
我检查了这些SQL语句的写法,发现很多地方可以优化。
比如,有些地方使用了子查询,我尝试将其改为连接查询,以提高查询效率。
2.检查索引。
我发现有些表上没有合适的索引,导致查询速度变慢。
于是,我添加了合适的索引,以提高查询速度。
3.调整SQL语句的顺序。
有些SQL语句的执行顺序不当,导致查询速度变慢。
我调整了这些语句的顺序,使其更加合理。
二、调整数据库参数1.增加缓存。
我发现数据库的缓存设置比较低,导致查询时需要频繁读取磁盘。
我适当增加了缓存大小,以提高查询速度。
2.调整线程数。
我发现数据库的线程数设置较低,无法充分利用CPU资源。
我将线程数调整为合适的值,以提高数据库的处理能力。
3.优化数据库配置。
我对数据库的配置文件进行了调整,比如调整了日志文件的存储路径和大小,以及调整了数据库的备份策略等。
三、检查硬件资源1.检查CPU。
我查看了CPU的使用情况,发现CPU负载较高。
我建议公司采购更强大的CPU,以提高数据库的处理能力。
2.检查内存。
我发现内存的使用率也很高,于是建议公司增加内存容量。
3.检查磁盘。
我检查了磁盘的读写速度,发现磁盘的I/O性能较低。
我建议公司更换更快的磁盘,以提高数据库的读写速度。
四、定期维护1.定期清理数据库。
首先,要了解在Oracle中Sql语句运行的机制。
以下是sql语句的执行步骤:1)语法分析,分析语句的语法是否符合规范,衡量语句中各表达式的意义。
2)语义分析,检查语句中涉及的所有数据库对象是否存在,且用户有相应的权限。
3)视图转换,将涉及视图的查询语句转换为相应的对基表查询语句。
4)表达式转换,将复杂的SQL 表达式转换为较简单的等效连接表达式。
5)选择优化器,不同的优化器一般产生不同的“执行计划”6)选择连接方式,ORACLE 有三种连接方式,对多表连接ORACLE 可选择适当的连接方式。
7)选择连接顺序,对多表连接ORACLE 选择哪一对表先连接,选择这两表中哪个表做为源数据表。
8)选择数据的搜索路径,根据以上条件选择合适的数据搜索路径,如是选用全表搜索还是利用索引或是其他的方式。
9)运行“执行计划”。
这里不得不提的是Oracle共享原理:将执行过的SQL语句存放在内存的共享池(shared buffer pool)中,可以被所有的数据库用户共享当你执行一个SQL语句(有时被称为一个游标)时,如果它和之前的执行过的语句完全相同, Oracle就能很快获得已经被解析的语句以及最好的执行路径. 这个功能大大地提高了SQL的执行性能并节省了内存的使用。
在了解了SQL语句的运行机制与Oracle共享原理后,我们可以知道SQL语句的书写方式对SQL语句的执行效率有很大的影响。
那么下面我们了解一下SQL中Select语句中各个关键字执行的顺序。
SQL语言不同于其他编程语言的最明显特征是处理代码的顺序。
在大多数据库语言中,代码按编码顺序被处理。
但在SQL语句中,第一个被处理的子句是FROM,而不是第一出现的SELECT。
SQL查询处理的步骤序号:(8) SELECT (9) DISTINCT (11) <TOP_specification> <select_list>(1) FROM <left_table>(3) <join_type> JOIN <right_table>(2) ON <join_condition>(4) WHERE <where_condition>(5) GROUP BY <group_by_list>(6) WITH {CUBE | ROLLUP}(7) HA VING <having_condition>(10) ORDER BY <order_by_list>以上每个步骤都会产生一个虚拟表,该虚拟表被用作下一个步骤的输入。
这些虚拟表对调用者(客户端应用程序或者外部查询)不可用。
只有最后一步生成的表才会会给调用者。
如果没有在查询中指定某一个子句,将跳过相应的步骤。
逻辑查询处理阶段简介:1、FROM:对FROM子句中的前两个表执行笛卡尔积(交叉联接),生成虚拟表VT1。
表名执行顺序是从后往前,所以数据较少的表尽量放后。
2、ON:对VT1应用ON筛选器,只有那些使为真才被插入到TV2。
3、OUTER (JOIN):如果指定了OUTER JOIN(相对于CROSS JOIN或INNER JOIN),保留表中未找到匹配的行将作为外部行添加到VT2,生成TV3。
如果FROM子句包含两个以上的表,则对上一个联接生成的结果表和下一个表重复执行步骤1到步骤3,直到处理完所有的表位置。
4、WHERE:对TV3应用WHERE筛选器,只有使为true的行才插入TV4。
执行顺序为从前往后或者说从左到右。
5、GROUP BY:按GROUP BY子句中的列列表对TV4中的行进行分组,生成TV5。
执行顺序从左往右分组。
6、CUTE|ROLLUP:把超组插入VT5,生成VT6。
7、HA VING:对VT6应用HA VING筛选器,只有使为true的组插入到VT7。
Having 语句很耗资源,尽量少用8、SELECT:处理SELECT列表,产生VT8。
9、DISTINCT:将重复的行从VT8中删除,产品VT9。
10、ORDER BY:将VT9中的行按ORDER BY子句中的列列表顺序,生成一个游标(VC10)。
执行顺序从左到右,是一个很耗资源的语句。
11、TOP:从VC10的开始处选择指定数量或比例的行,生成表TV11,并返回给调用者。
看到这里,应该是清楚了整个SQL语句整个执行的过程,那么我们就接下来进一步要坐得就是在实现功能同时有考虑性能的思想,努力提高SQL的执行效率。
第一、只返回需要的数据返回数据到客户端至少需要数据库提取数据、网络传输数据、客户端接收数据以及客户端处理数据等环节,如果返回不需要的数据,就会增加服务器、网络和客户端的无效劳动,其害处是显而易见的,避免这类事件需要注意:A、横向来看,(1)不要写SELECT *的语句,而是选择你需要的字段。
(2)当在SQL语句中连接多个表时, 请使用表的别名并把别名前缀于每个Column上.这样一来,就可以减少解析的时间并减少那些由Column歧义引起的语法错误。
B、纵向来看,(1)合理写WHERE子句,不要写没有WHERE的SQL语句。
(2) SELECT TOP N * --没有WHERE条件的用此替代第二、尽量少做重复的工作A、控制同一语句的多次执行,特别是一些基础数据的多次执行是很多程序员很少注意的。
B、减少多次的数据转换,也许需要数据转换是设计的问题,但是减少次数是程序员可以做到的。
C、杜绝不必要的子查询和连接表,子查询在执行计划一般解释成外连接,多余的连接表带来额外的开销。
D、合并对同一表同一条件的多次UPDA TE。
E、UPDA TE操作不要拆成DELETE操作+INSERT操作的形式,虽然功能相同,但是性能差别是很大的。
第三、注意临时表和表变量的用法在复杂系统中,临时表和表变量很难避免,关于临时表和表变量的用法,需要注意:A、如果语句很复杂,连接太多,可以考虑用临时表和表变量分步完成。
B、如果需要多次用到一个大表的同一部分数据,考虑用临时表和表变量暂存这部分数据。
C、如果需要综合多个表的数据,形成一个结果,可以考虑用临时表和表变量分步汇总这多个表的数据。
D、其他情况下,应该控制临时表和表变量的使用。
E、关于临时表和表变量的选择,很多说法是表变量在内存,速度快,应该首选表变量,但是在实际使用中发现,(1)主要考虑需要放在临时表的数据量,在数据量较多的情况下,临时表的速度反而更快。
(2)执行时间段与预计执行时间(多长)F、关于临时表产生使用SELECT INTO和CREA TE TABLE + INSERT INTO的选择,一般情况下,SELECT INTO会比CREA TE TABLE + INSERT INTO的方法快很多,但是SELECT INTO会锁定TEMPDB的系统表SYSOBJECTS、SYSINDEXES、SYSCOLUMNS,在多用户并发环境下,容易阻塞其他进程,所以我的建议是,在并发系统中,尽量使用CREA TE TABLE + INSERT INTO,而大数据量的单个语句使用中,使用SELECT INTO。
第四、注意子查询的用法子查询是一个SELECT 查询,它嵌套在SELECT、INSERT、UPDA TE、DELETE 语句或其它子查询中。
任何允许使用表达式的地方都可以使用子查询,子查询可以使我们的编程灵活多样,可以用来实现一些特殊的功能。
但是在性能上,往往一个不合适的子查询用法会形成一个性能瓶颈。
如果子查询的条件中使用了其外层的表的字段,这种子查询就叫作相关子查询。
相关子查询可以用IN、NOT IN、EXISTS、NOT EXISTS引入。
关于相关子查询,应该注意:(1)A、NOT IN、NOT EXISTS的相关子查询可以改用LEFT JOIN代替写法。
比如:SELECT PUB_NAMEFROM PUBLISHERSWHERE PUB_ID NOT IN (SELECT PUB_ID FROM TITLES WHERE TYPE = 'BUSINESS') 可以改写成:SELECT A.PUB_NAMEFROM PUBLISHERS A LEFT JOIN TITLES B ON B.TYPE = 'BUSINESS' AND A.PUB_ID=B. PUB_IDWHERE B.PUB_ID IS NULL(2)SELECT TITLEFROM TITLESWHERE NOT EXISTS (SELECT TITLE_ID FROM SALES WHERE TITLE_ID = TITLES.TITLE_ID)可以改写成:SELECT TITLEFROM TITLES LEFT JOIN SALES ON SALES.TITLE_ID = TITLES.TITLE_IDWHERE SALES.TITLE_ID IS NULLB、如果保证子查询没有重复,IN、EXISTS的相关子查询可以用INNER JOIN 代替。
比如:SELECT PUB_NAMEFROM PUBLISHERSWHERE PUB_ID IN (SELECT PUB_ID FROM TITLESWHERE TYPE = 'BUSINESS')可以改写成:SELECT DISTINCT A.PUB_NAMEFROM PUBLISHERS A INNER JOIN TITLES B ON B.TYPE = 'BUSINESS' AND A.PUB_ID=B. PUB_IDC、IN的相关子查询用EXISTS代替,比如SELECT PUB_NAMEFROM PUBLISHERSWHERE PUB_ID IN (SELECT PUB_ID FROM TITLES WHERE TYPE = 'BUSINESS')可以用下面语句代替:SELECT PUB_NAMEFROM PUBLISHERSWHERE EXISTS (SELECT 1 FROM TITLES WHERE TYPE = 'BUSINESS' AND PUB_ID= PUBLISHERS.PUB_ID) D、不要用COUNT(*)的子查询判断是否存在记录,最好用LEFT JOIN或者EXISTS,比如有人写这样的语句:SELECT JOB_DESCFROM JOBSWHERE (SELECT COUNT(*) FROM EMPLOYEE WHERE JOB_ID=JOBS.JOB_ID)=0应该改成:SELECT JOBS.JOB_DESCFROM JOBS LEFT JOIN EMPLOYEE ON EMPLOYEE.JOB_ID=JOBS.JOB_IDWHERE EMPLOYEE.EMP_ID IS NULLSELECT JOB_DESC FROM JOBS WHERE (SELECT COUNT(*) FROM EMPLOYEE WHERE JOB_ID=JOBS.JOB_ID)<>0应该改成:SELECT JOB_DESC FROM JOBSWHERE EXISTS (SELECT 1 FROM EMPLOYEE WHERE JOB_ID=JOBS.JOB_ID)第五、尽量使用索引,并注意对含索引列的运算建立索引后,并不是每个查询都会使用索引,在使用索引的情况下,索引的使用效率也会有很大的差别。