- 浏览: 143855 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
lliiqiang:
因为纯查询不会产生数据逻辑错误,所以sql语句查询顺序可以被颠 ...
要提高SQL查询效率where语句条件的先后次序应如何写 使你的 SQL 语句完全优化 -
zqb666kkk:
哥们写的 不错 比网上其他 的齐全多了
oracle9i 冷备份 -
xianwu13:
Oracle truncate table, delete, drop table的区别 -
xianwu13:
讲的太好了 ,狂顶,
Oracle truncate table, delete, drop table的区别 -
xianwu13:
讲的太好了 ,狂顶,支持[size=xx-large][/si ...
Oracle truncate table, delete, drop table的区别
Oracle数据库的配置和SQL语句的优化 。
INSERT/*+append*/INTO t_servicexx(serviceid,clientid,prod_id,serviceno,addrid,
connectno,fgsid,gl_serviceid,up_serviceid,servlev,
dialacctname,ibss_id,gl_serviceid_num,phone_nbr,orgid)
2 Oracle数据库的配置
2.1 影响SQL效率的关键因素和配置:
Oracle数据库上的设置对其性能的影响很大,如Shared Pool Size、Buffer Cache Size、SGA Structures、Database I/O Configuration、Rollback Segments等等,这些是DBA(数据库管理员)要根据实际状况需性能调整的部分。
我们在平时工作中用到大量的View,View中SQL的写法对效率的影响很大,首先有必要了解一条SQL语句是如何被执行的。当SQL语句进入Oracle的缓存后,在该语句准备执行之前,DBMS将执行下列步骤:
⑴ SQL语法检查:检查SQL语句拼写是否正确和词序。
⑵ SQL语义分析:核实所有的与数据字典不一致的表和列的名字。
⑶ 生成执行计划:使用优化规则和数据字典中的统计表来决定最佳执行计划。
⑷ 建立可执行的二进制代码:基于执行计划,Oracle生成二进制执行代码。
⑸ 抓取并返回需要的数据。
其中第三步生成执行计划非常关键,所谓执行计划,就是对一个查询任务,做出一份怎样去完成任务的详细方案。对于查询而言,我们提交的SQL仅仅是描述出了我们的目的,但Oracle内部怎么去得到这些数据,是由数据库DBMS来决定的。
所以执行计划产生的好坏直接影响SQL运行的效能。
2.3 ORACLE优化器
在不同的情况下,同一条SQL可能有多种执行计划。但理论上在某一时点,一定只有一种执行计划是最优的、花费时间是最少的。执行计划的工作是由优化器(Optimizer)来完成的,我们先要了解一下Oracle的优化器:
2.3.1 ORACLE优化器的优化方式
ORACLE优化器的优化方式有两大类,即基于规则的优化方式(Rule-Based Optimization,简称为RBO)和基于代价的优化方式(Cost-Based Optimization,简称为CBO)。
⑴ RBO方式:优化器在分析SQL语句时,根据数据库中表和索引等定义信息,遵循的是Oracle内部预定的一些规则。比如我们常见的:当一个where子句中的一列有索引时去走索引而不走全表扫描。
⑵ CBO方式:依词义可知,它是看语句的代价(Cost)了。基于代价的查询,数据库根据搜集的表和索引的数据的统计信息(统计信息通过analyze 命令或者使用dbms_stats包来搜集)综合来决定选取一个数据库认为最优的执行计划。统计信息给出表的大小 、有多少行、每行的长度等信息。
注意:这些统计信息起初在库内是没有的,是根据 analyze 命令或者dbms_stats包来定期搜集后才出现的,所以很多的时候过期统计信息会令优化器做出一个错误的执行计划,因此我们应及时更新这些信息。为了使用基于成本的优化器(CBO) , 你必须经常运行analyze或dbms_stats命令,以增加数据库中的对象统计信息(object statistics)的准确性。
在Oracle8及以后的版本,Oracle强列推荐用CBO的方式。
注意:这些统计信息起初在库内是没有的,是根据 analyze 命令或者dbms_stats包来定期搜集后才出现的,所以很多的时候过期统计信息会令优化器做出一个错误的执行计划,因此我们应及时更新这些信息。为了使用基于成本的优化器(CBO) , 你必须经常运行analyze或dbms_stats命令,以增加数据库中的对象统计信息(object statistics)的准确性。
在Oracle8及以后的版本,Oracle强列推荐用CBO的方式。
优化模式包括Rule,Choose,First rows,All rows这四种方式,先解释一下:
⑴ Rule:即走基于规则的方式。
⑵ First_Rows:基于成本的方式。指执行计划采用最少资源尽快的返回部分结果给客户端,它将是以最快的方式返回查询的最先的几行,从总体上减少了响应时间,对于排序分页页显示这种查询尤其适用。
⑶ All_Rows:基于成本的方式。当一个表有统计信息时,它将以最快的方式返回表的所有的行,从总体上提高查询的吞吐量。没有统计信息则走基于规则的方式。
⑷ Choose:这是我们应关注的,默认的情况下Oracle用的便是这种方式。指的是当一个表或索引有统计信息(指运行过analyze 命令或者使用过dbms_stats包来搜集),则走CBO的方式 (在CHOOSE模式下ORACLE采用的是 FIRST_ROWS);如果表或索引没统计信息,那么走RBO的方式。
注:Oracle ERP 11i之前的版本,默认用RULE;Oracle ERP 11i之后的版本,默认用CHOOSE。
2.3.3 Optimizer mode优化模式级别的设定:
⑴ Instance级别:我们可以通过在<init>.ora文件中设定OPTIMIZER_MODE=<Mode>去选用。
⑵ Sessions级别:通过SQL> ALTER SESSION SET OPTIMIZER_MODE=<Mode>;来设定。
⑶ 语句级别,这些需要用到Hint,比如:
⑵ Sessions级别:通过SQL> ALTER SESSION SET OPTIMIZER_MODE=<Mode>;来设定。
⑶ 语句级别,这些需要用到Hint,比如:
SELECT /*+ rule */ ordh.order_number,ordl.ordered_item
FROM apps.oe_order_headers_all ordh, apps.oe_order_lines_all ordl
WHERE ordh.header_id = ordl.header_id;
对CBO模式,对象统计信息至关重要。我们可以用如下SQL查询到:
SELECT table_name,num_rows, blocks, empty_blocks AS empty, avg_space, chain_cnt, avg_row_len
FROM dba_tables
WHERE owner = 'ONT' AND table_name = 'OE_ORDER_LINES_ALL'
TABLE_NAME
|
NUM_ROWS
|
BLOCKS
|
EMPTY
|
AVG_SPACE
|
CHAIN_CNT
|
AVG_ROW_LEN
|
OE_ORDER_LINES_ALL
|
4344
|
505
|
5
|
0
|
0
|
441
|
可以看到数据字典中统计到的该表有5344笔记录
Oracle ERP11i用的optimizer_mode是choose,且Oracle强烈建议要定期运行FND_STATS。
Oracle DB中常用的Gather有以下一些,DBA也可以直接在Database级别上定期Run这些Function,以便能让Oracle统计到最新的数据库状况:
dbms_stats.gather_database_stats();
dbms_stats.gather_schema_stats();
dbms_stats.gather_table_stats();
dbms_stats.gather_index_stats();
dbms_stats.gather_schema_stats();
dbms_stats.gather_table_stats();
dbms_stats.gather_index_stats();
2.5 跟踪 SQL实际运行的Cost
执行计划是Oracle根据一些统计信息去“估计”出各个步骤所耗的Cost,与实际的执行过程所耗Cost不见得一样。实际执行过程耗的CPU、Disk IO等资源的数量可以通过sql_trace统计出来。所以Tuning SQL不仅要看“执行计划”,有时还必须结合trace的Log去分析。
3 SQL语句的优化:
SQL语句的优化是需要不断尝试的,在此把自己的经验分享一二。
3.1 绝大多数情况下not exists比not in 效率高
3.2 UNION ALL效率比UNION高很多
3.3 一些很耗资源的SQL操作,在不必要的情况下不要使用
Select *,Order by,Group by,Distinct, UNION, MINUS,INTERSECT 操作是相当耗时的,在View中能不使用就不要使用。 通常, 带有UNION, MINUS , INTERSECT的SQL语句都可以用其它方式重写。
尽量在 SELECT 子句里面用联接查询,少用子查询。因为子查询所得到的子Table的数据量等信息是Oracle无法事前统计出来的,所以优化器也很难得出一个优化过的执行计划。
如果Table上有索引,则系统访问带索引的Field时,可通过访问索引中的栏位来快速获得相对应记录的ROWID,而通常情况下,使用索引比全表扫描要块几倍乃至几千倍。
Oracle ERP中几乎所有的Table都设有索引,尽量以索引中的栏位做 join,避免用我们认为值是唯一的栏位去串
3.6 在View中尽量不要使用 Package/function 来得到栏位值,
在view中尽量不要引用function,否则会增加一定的通讯开销。简单的判断尽量用decode,nvl,case when等实现。
3.7 通过ROWID访问表
ORACLE 采用两种访问表中记录的方式:
⑴ 全表扫描
全表扫描就是顺序地访问表中每条记录. ORACLE采用一次读入多个数据块(database block)的方式优化全表扫描.
⑵ 通过ROWID访问表
如果可以,强烈采用基于ROWID的访问方式情况以提高访问表的效率。ROWID包含了表中记录的物理位置信息,ORACLE采用索引实现了数据和存放数据的物理位置之间的联系, 通常索引提供了快速访问ROWID的方法,因此那些基于索引列的查询就可以得到性能上的提高。
3.8 必要时可在Oracle原表上加索引
3.9 合理排列WHERE子句中的连接顺序.
ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,那些可以过滤掉最大数量记录的条件最好写在WHERE子句的末尾。虽然对简单SQL,Oracle优化器自动会去调整顺序,但还是建议将能过滤掉最多记录的Where条件放在最后。
3.10 用Where子句替换HAVING子句
避免使用HAVING子句, HAVING 只会在检索出所有记录之后才对结果集进行过滤。 这个处理需要排序,总计等操作。 如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销。
3.11 关于使用索引(Index)的一些注意点
而通常情况下,使用索引比全表扫描要块几倍至几千倍。某些情况下SELECT 语句中的WHERE子句用到索引列,但生成的执行计划却不使用索引。这里有一些例子.
- ‘!=’,NOT操作将不使用索引.
- ‘||’是字符连接函数. 就象其它函数那样, 停用了索引.
- 相同的索引列不能互相比较,这将会启用全表扫描.
- 避免在索引列上使用计算.
3.12 识别 “低效运行”的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 sql_text like '%XX%' AND EXECUTIONS>0 AND BUFFER_GETS > 0 AND (BUFFER_GETS-DISK_READS)/BUFFER_GETS < 0.8
ORDER BY 4 DESC;
FROM V$SQLAREA
WHERE sql_text like '%XX%' AND EXECUTIONS>0 AND BUFFER_GETS > 0 AND (BUFFER_GETS-DISK_READS)/BUFFER_GETS < 0.8
ORDER BY 4 DESC;
发表评论
-
行列置换oracle
2011-10-28 11:31 963create table sale_list( ... -
oracle递归查询
2011-10-28 10:08 1042有的情况下,我们需要用递归的方法整理数据,这才程序中很容易做到 ... -
自动脚本发布工具
2011-01-06 10:05 1106自动脚本发布工具 -
在服务器上杀oracle全部进程
2011-01-04 17:47 715kill -9 `ps -ef|grep LOCAL=NO|g ... -
sql分组相关
2010-12-30 10:30 759/* create table Inventory ( ... -
数据泵expdp&impdp
2010-08-19 17:09 775Oracle Database 10g引入了最新的数据泵(Da ... -
创建非唯一索引脚本的方法
2010-07-02 09:44 1149导出创建非唯一索引脚本的方法 在ORACLE里用逻辑备份 ... -
创建用户、密码、权限等
2010-06-09 14:16 909Windows下启动服务: O ... -
PLSQL 存储过程动态创建表
2010-05-26 09:11 21491、SQLPLUS登录 SQ ... -
oracle 实例与数据库
2010-05-26 09:10 12851、“实例”(instance) ... -
oracle9i 冷备份
2010-05-26 09:06 16001、 冷备份发生在数据 ... -
Excel导入到oracle中对应的表
2010-04-22 20:44 11201、将excel文件(F)→另存为(A)→保存类型为:制表符分 ... -
ORA-28000: the account is locked-的解决办法
2010-04-05 23:27 6357ORA-28000: the account is locke ... -
oracle中对排序的总结
2010-03-26 15:05 775-- 按拼音排序 (系统默认) select * f ... -
Oracle truncate table, delete, drop table的区别
2010-03-13 01:06 6632Oracle truncate table, delete, ... -
linux环境下oracle备份脚本
2010-03-13 00:45 1395#!/bin/shsource /home/oracle/.b ... -
Oracle数据库的备份(热、冷、exp)与恢复
2010-03-13 00:43 1346Oracle数据库的备份与恢复 ---- 当我 ... -
Start with...Connect By子句递归查询一般用于一个表维护树形结构的应用
2010-03-09 14:22 868Start with...Connect By子句递归查询一般 ... -
在windows xp环境下如何完全卸载 oracle9i
2010-01-11 11:51 1560在windows xp环境下如何完全卸载 oracle9i ... -
要提高SQL查询效率where语句条件的先后次序应如何写 使你的 SQL 语句完全优化
2009-12-01 17:36 5528我们要做到不但会写SQL ...
相关推荐
INSERT /*+ append */ INTO TABLE1 AS SELECT * FROM TABLE2; ``` 此语句表示使用Append模式将 `TABLE2` 中的所有数据插入到 `TABLE1` 中。 #### 三、使用场景及注意事项 - **适用场景:** - **批量数据导入:**...
【实验一:安装和配置Oracle数据库与使用SQL*plus】 实验目标是让学生深入了解Oracle数据库的安装过程,掌握数据库的创建和配置,理解Oracle数据库的存储结构,熟悉参数文件的应用,并熟练使用SQL*plus命令行工具...
里面是ORACLE SQL 优化时会用到的hint示例汇总。总共有30个hint。 全部都是hint说明及示例。下面展示一个示例。 /*+noappend*/ 通过在插入语句生存期内停止...insert /*+noappend*/ into test1 select * from test4 ;
sql.append("insert into ex_log(EX_LOG_ID, EX_LOG_DATE) values(?, ?)"); ``` 这里的`EX_LOG_ID`和`EX_LOG_DATE`是目标表`ex_log`中的列名,而`?`表示参数占位符,实际执行时将被具体的值替换。 #### 3. 加载...
INSERT /*+append*/ INTO wjg_test5 SELECT * FROM wjg_test4 t4 WHERE ROWNUM ; ``` 由于非车险定价系统中的表操作往往涉及重新构建,如使用`TRUNCATE`语句,因此`append` hint的使用不会影响数据布局。 **五...
- **解析**:使用`/*+append*/`提示可以在执行大量插入操作时提高性能,因为它绕过了某些Oracle默认的检查和操作,例如一致性检查和回滚段使用。 - **优化建议**:当插入大量数据时,考虑使用`/*+append*/`提示,但...
- **SQL*Plus** 是Oracle提供的一种命令行工具,用户可以通过它直接与Oracle数据库交互,执行SQL语句和PL/SQL块。 - 在Windows环境下,可以通过命令行输入 `sqlplus username/password@database` 来登录,其中`...
INSERT /*+ APPEND */ INTO table_name SELECT * FROM table_name1; ``` - **作用**:使用`APPEND`提示可以让Oracle直接向表末尾插入数据,从而避免了中间数据页的分裂操作,加快了插入速度。 - **适用场景**:...
24. **append** / **clear** / **copy** / **count** / **insert** / **pop** / **remove** / **reverse** / **sort**:列表方法,用于操作列表元素。 25. **add** / **discard** / **difference** / **...
SQL*Plus是Oracle数据库管理员和开发人员的重要工具,它提供了丰富的功能,包括数据操作、数据库管理、对象描述以及SQL语句的快速编辑。通过熟练掌握SQL*Plus,用户可以高效地与Oracle数据库进行交互,提升工作效率...
综上所述,这份文档涵盖了 Oracle8i 数据库的基础知识,包括 SQL*PLUS 的使用、PL/SQL 的基础、表结构的管理、高级特性如视图、存储过程等,以及一些更深入的主题如序列和同义词的使用。这对于想要学习或加深对 ...
void insert(); /*插入*/ void append(); /*追加*/ void copy(); /*复制文件*/ void sort(); /*排序*/ void index(); /*索引*/ void total(); /*分类合计*/ void list(); /*显示所有数据*/ void print(SALARY *p); /...
sqlInserts.Append($"INSERT INTO yourTable ({reader.GetName(i)}) VALUES ('{escapedValue}');\n"); } sqlInserts.AppendLine("\n"); // 添加新行分隔 } ``` 4. **保存为TXT文件**: 使用`StreamWriter`类...
1. **直接路径插入**:使用`INSERT /*+APPEND*/`语句,可以将数据直接写入数据文件,绕过Oracle的标准缓冲区,提高加载速度。但是,这种方法不支持回滚,因此在事务性要求较高的场景下需谨慎使用。 2. **并行插入**...
Oracle数据库中的Copy命令是SQL*Plus提供的一种便捷的数据复制工具,尤其对于DBA来说,它在处理表间数据复制任务时具有较高的效率。Copy命令允许用户在同一个数据库的不同表之间,甚至不同服务器的数据库之间复制...
从给定的文件信息中,我们可以提炼出一系列关于Oracle9i数据库开发的关键知识点,这些知识点不仅涵盖了Oracle9i的基础操作,还深入到了SQL*PLUS和PL/SQL的使用技巧,对于初学者和有一定经验的数据库开发者来说都是...