oracle的报表的典型sql语句
oracle sql并发查询语句
oracle sql并发查询语句Oracle SQL是一种强大的关系型数据库管理系统,支持并发查询,可以同时处理多个查询请求。
下面列举了十个符合题目要求的Oracle SQL并发查询语句。
1. 查询所有员工的姓名和工资```sqlSELECT 姓名, 工资 FROM 员工表;```2. 查询员工工资大于5000元的部门名称和平均工资```sqlSELECT 部门名称, AVG(工资) AS 平均工资FROM 员工表WHERE 工资 > 5000GROUP BY 部门名称;```3. 查询销售额最高的产品名称和销售额```sqlSELECT 产品名称, MAX(销售额) AS 最高销售额FROM 销售表GROUP BY 产品名称ORDER BY 最高销售额 DESCFETCH FIRST ROW ONLY;```4. 查询在某个日期范围内有销售记录的员工姓名和销售数量```sqlSELECT 姓名, COUNT(*) AS 销售数量FROM 员工表INNER JOIN 销售表 ON 员工表.员工ID = 销售表.员工ID WHERE 销售日期BETWEEN TO_DATE('2021-01-01', 'YYYY-MM-DD') AND TO_DATE('2021-12-31', 'YYYY-MM-DD') GROUP BY 姓名;```5. 查询每个部门的员工数量和平均工资```sqlSELECT 部门名称, COUNT(*) AS 员工数量, AVG(工资) AS 平均工资FROM 员工表GROUP BY 部门名称;```6. 查询没有销售记录的产品名称和库存数量```sqlSELECT 产品名称, 库存数量FROM 产品表WHERE 产品ID NOT IN (SELECT 产品ID FROM 销售表);```7. 查询员工工资排名前10的姓名和工资```sqlSELECT 姓名, 工资FROM (SELECT 姓名, 工资, RANK() OVER (ORDER BY 工资 DESC) AS 排名FROM 员工表)WHERE 排名 <= 10;```8. 查询每个部门的销售总额和销售数量```sqlSELECT 部门名称, SUM(销售额) AS 销售总额, COUNT(*) AS 销售数量FROM 员工表INNER JOIN 销售表 ON 员工表.员工ID = 销售表.员工ID GROUP BY 部门名称;```9. 查询在某个日期之后有销售记录的产品名称和最早销售日期```sqlSELECT 产品名称, MIN(销售日期) AS 最早销售日期FROM 产品表INNER JOIN 销售表 ON 产品表.产品ID = 销售表.产品ID WHERE 销售日期 > TO_DATE('2021-01-01', 'YYYY-MM-DD') GROUP BY 产品名称;```10. 查询销售额排名前5的员工姓名和销售额```sqlSELECT 姓名, 销售额FROM (SELECT 姓名, 销售额, RANK() OVER (ORDER BY 销售额DESC) AS 排名FROM 员工表INNER JOIN 销售表 ON 员工表.员工ID = 销售表.员工ID) WHERE 排名 <= 5;```以上是十个符合题目要求的Oracle SQL并发查询语句。
oracle查询表结构sql语句
oracle查询表结构sql语句在Oracle数据库中,查询表结构的SQL语句可以通过查询数据库的系统表来实现。
以下是一些常用的查询表结构的SQL语句。
1. 查询表的所有列名和数据类型:```SELECT column_name, data_typeFROM all_tab_columnsWHERE table_name = '表名';```这条SQL语句会返回指定表的所有列名和对应的数据类型。
2. 查询表的主键列:```SELECT constraint_name, column_nameFROM all_cons_columnsWHERE table_name = '表名' AND constraint_name = 'PK_表名';```这条SQL语句会返回指定表的主键列名。
3. 查询表的外键列:```SELECT constraint_name, column_name, r_constraint_name, r_table_nameFROM all_cons_columnsWHERE table_name = '表名' AND constraint_name LIKE 'FK_%';```这条SQL语句会返回指定表的外键列名、相关联的表名和外键约束名。
4. 查询表的索引:```SELECT index_name, column_nameFROM all_ind_columnsWHERE table_name = '表名';```这条SQL语句会返回指定表的索引名和对应的列名。
5. 查询表的约束:```SELECT constraint_name, constraint_typeFROM all_constraintsWHERE table_name = '表名' AND constraint_type IN ('P', 'U', 'R', 'C');```这条SQL语句会返回指定表的主键约束、唯一约束、外键约束和检查约束。
oracle查询表语句
oracle查询表语句查询所有数据:SELECT * FROM 表名;查询指定列数据:SELECT 列名1, 列名2, 列名3 FROM 表名;带条件查询:SELECT 列名1, 列名2 FROM 表名 WHERE 条件;排序查询:SELECT 列名1, 列名2 FROM 表名 ORDER BY 列名ASC/DESC;聚合查询:SELECT 列名, 聚合函数(列名) FROM 表名 GROUP BY 列名;连接查询:SELECT 表1.列名, 表2.列名 FROM 表1 JOIN 表2 ON 表1.关联列 = 表2.关联列;子查询:SELECT 列名 FROM 表名 WHERE 列名 IN (SELECT 列名FROM 表名 WHERE 条件);复杂查询:SELECT 列名 FROM 表名 WHERE 条件 UNION SELECT 列名FROM 表名 WHERE 条件;其他:- 查询结果去重:SELECT DISTINCT 列名 FROM 表名;- 限制查询结果行数:SELECT * FROM 表名 LIMIT num;- 分页查询:SELECT * FROM 表名 LIMIT num OFFSET offset;- 对查询结果取别名:SELECT 列名 AS 别名 FROM 表名;- 对查询结果进行计数:SELECT COUNT(*) FROM 表名;- 对查询结果进行求和、平均值、最大值、最小值等计算:SELECT SUM(列名) FROM 表名;SELECT AVG(列名) FROM 表名;SELECT MAX(列名) FROM 表名;SELECT MIN(列名) FROM 表名;注意:其中"表名"需要替换为实际表的名称,"列名"需要替换为实际列的名称,"条件"需要替换为实际查询条件。
Oracle维护常用SQL语句(查询系统表和视图)
from dba_tablespaces t, dba_data_files d
where t.tablespace_name = d.tablespace_name
group by t.tablespace_name;
2、查看表空间物理文件的名称及大小
select tablespace_name, file_id, file_name,
order by segment_name ;
4、查看控制文件
select name from v$controlfile;
5、查看日志文件
select member from v$logfile;
6、查看表空间的使用情况
select sum(bytes)/(1024*1024) as free_space,tablespace_name
column opname format a16
column progress format a8
select username,sid,opname,
round(sofar*100 / totalwork,0) || '%' as progress,
time_remaining,sql_text
v$lock l where s.sid = l.sid ) ls where o.object_id = ls.id1 and o.owner
3)根据sid查看对应连接正在运行的sql
24.查询表空间使用情况
25.查询表空间的碎片程度
26.查询正在运行的数据库实例
1、查看表空间的名称及大小
select t.tablespace_name, round(sum(bytes/(1024*1024)),0) ts_size
oracle常用SQL语句(汇总版)
Oracle数据库常用sql语句ORACLE 常用的SQL语法和数据对象一.数据控制语句(DML) 部分1.INSER T (往数据表里插入记录的语句)INSERT INTO 表名(字段名1, 字段名2, ……) VALUES ( 值1, 值2, ……);INSERT INTO 表名(字段名1, 字段名2, ……) SELECT (字段名1, 字段名2, ……) FROM 另外的表名;字符串类型的字段值必须用单引号括起来, 例如: ’GOOD DAY’如果字段值里包含单引号’ 需要进行字符串转换, 我们把它替换成两个单引号''.字符串类型的字段值超过定义的长度会出错, 最好在插入前进行长度校验.日期字段的字段值可以用当前数据库的系统时间SYSDATE, 精确到秒或者用字符串转换成日期型函数TO_DATE(‘2001-08-01’,’YYYY-MM-DD’)TO_DATE()还有很多种日期格式, 可以参看OR ACLE DOC.年-月-日小时:分钟:秒的格式YYYY-MM-DD HH24:MI:SSINSERT时最大可操作的字符串长度小于等于4000个单字节, 如果要插入更长的字符串, 请考虑字段用CLOB类型,方法借用ORACLE里自带的DBMS_LOB程序包.INSERT时如果要用到从1开始自动增长的序列号, 应该先建立一个序列号CREATE SEQUENCE 序列号的名称(最好是表名+序列号标记) INCREMENT BY 1 START WI TH 1 MAXVALUE 99999 CYCLE NOCACHE;其中最大的值按字段的长度来定, 如果定义的自动增长的序列号NUMBER(6) , 最大值为999999 INSERT 语句插入这个字段值为: 序列号的名称.NEXTVAL2.DELETE (删除数据表里记录的语句)DELETE FROM表名 WHERE 条件;注意:删除记录并不能释放ORACLE里被占用的数据块表空间. 它只把那些被删除的数据块标成unused.如果确实要删除一个大表里的全部记录, 可以用TRUNCATE 命令, 它可以释放占用的数据块表空间TRUNCATE TABLE 表名;此操作不可回退.3.UPDATE (修改数据表里记录的语句)UPDATE表名SET 字段名1=值1, 字段名2=值2, …… WHERE 条件;如果修改的值N没有赋值或定义时, 将把原来的记录内容清为NULL, 最好在修改前进行非空校验;值N超过定义的长度会出错, 最好在插入前进行长度校验..注意事项:A. 以上SQL语句对表都加上了行级锁,确认完成后, 必须加上事物处理结束的命令COMMIT 才能正式生效,否则改变不一定写入数据库里.如果想撤回这些操作, 可以用命令ROLLBACK 复原.B. 在运行INSERT, DELETE 和UPDATE 语句前最好估算一下可能操作的记录范围,应该把它限定在较小(一万条记录) 范围内,. 否则ORACLE处理这个事物用到很大的回退段.程序响应慢甚至失去响应. 如果记录数上十万以上这些操作, 可以把这些SQL语句分段分次完成, 其间加上COMMIT 确认事物处理.二.数据定义(DDL) 部分1.CREATE (创建表, 索引, 视图, 同义词, 过程, 函数, 数据库链接等)ORACLE常用的字段类型有CHAR 固定长度的字符串VARCHAR2 可变长度的字符串NUMBER(M,N) 数字型M是位数总长度, N是小数的长度DATE 日期类型创建表时要把较小的不为空的字段放在前面, 可能为空的字段放在后面创建表时可以用中文的字段名, 但最好还是用英文的字段名创建表时可以给字段加上默认值, 例如DEFAUL T SYSDATE这样每次插入和修改时, 不用程序操作这个字段都能得到动作的时间创建表时可以给字段加上约束条件例如不允许重复UNIQUE, 关键字PRIMAR Y KEY2.AL TER (改变表, 索引, 视图等)改变表的名称AL TER TABLE 表名1 TO 表名2;在表的后面增加一个字段AL TER TABLE表名ADD 字段名字段名描述;修改表里字段的定义描述AL TER TABLE表名MODIFY字段名字段名描述;给表里的字段加上约束条件AL TER TABLE 表名ADD CONSTRAINT 约束名PRIMAR Y KEY (字段名);AL TER TABLE 表名ADD CONSTRAINT 约束名UNIQUE (字段名);把表放在或取出数据库的内存区AL TER TABLE 表名CACHE;AL TER TABLE 表名NOCACHE;3.DROP (删除表, 索引, 视图, 同义词, 过程, 函数, 数据库链接等)删除表和它所有的约束条件DROP TABLE 表名CASCADE CONSTRAINTS;4.TRUNCATE (清空表里的所有记录, 保留表的结构)TRUNCATE 表名;三.查询语句(SELECT) 部分SELECT字段名1, 字段名2, …… FROM 表名1, [表名2, ……] WHERE 条件;字段名可以带入函数例如: COUNT(*), MIN(字段名), MAX(字段名), AVG(字段名), DISTINCT(字段名), TO_CHAR(DATE字段名,'YYYY-MM-DD HH24:MI:SS')NVL(EXPR1, EXPR2)函数解释:IF EXPR1=NULLRETURN EXPR2ELSERETURN EXPR1DECODE(AA﹐V1﹐R1﹐V2﹐R2....)函数解释:IF AA=V1 THEN RETURN R1IF AA=V2 THEN RETURN R2..…ELSERETURN NULLLPAD(char1,n,char2)函数解释:字符char1按制定的位数n显示,不足的位数用char2字符串替换左边的空位字段名之间可以进行算术运算例如: (字段名1*字段名1)/3查询语句可以嵌套例如: SELECT …… FROM(SELECT …… FROM表名1, [表名2, ……] WHERE 条件) WHERE 条件2;两个查询语句的结果可以做集合操作例如: 并集UNION(去掉重复记录), 并集UNION ALL(不去掉重复记录), 差集MINUS, 交集INTERSECT分组查询SELECT字段名1, 字段名2, …… FROM 表名1, [表名2, ……] GROUP BY字段名1[HAVING 条件] ;两个以上表之间的连接查询SELECT字段名1, 字段名2, …… FROM 表名1, [表名2, ……] WHERE表名1.字段名= 表名2. 字段名[ AND ……] ;SELECT字段名1, 字段名2, …… FROM 表名1, [表名2, ……] WHERE表名1.字段名= 表名2. 字段名(+) [ AND ……] ;有(+)号的字段位置自动补空值查询结果集的排序操作, 默认的排序是升序ASC, 降序是DESCSELECT字段名1, 字段名2, …… FROM 表名1, [表名2, ……]ORDER BY字段名1, 字段名2 DESC;字符串模糊比较的方法INSTR(字段名, ‘字符串’)>0字段名LIKE ‘字符串%’[‘%字符串%’]每个表都有一个隐含的字段ROWID, 它标记着记录的唯一性.四.ORACLE里常用的数据对象 (SCHEMA)1.索引(INDEX)CREATE INDEX 索引名ON 表名( 字段1, [字段2, ……] );AL TER INDEX 索引名REBUILD;一个表的索引最好不要超过三个(特殊的大表除外), 最好用单字段索引, 结合SQL语句的分析执行情况, 也可以建立多字段的组合索引和基于函数的索引ORACLE8.1.7字符串可以索引的最大长度为1578 单字节ORACLE8.0.6字符串可以索引的最大长度为758 单字节2.视图(VIEW)CREATE VIEW 视图名AS SELECT …. FROM …..;AL TER VIEW视图名COMPILE;视图仅是一个SQL查询语句, 它可以把表之间复杂的关系简洁化.3.同义词(SYNONMY)CREATE SYNONYM同义词名FOR 表名;CREATE SYNONYM同义词名FOR 表名@数据库链接名;4.数据库链接(DATABASE LINK)CREATE DATABASE LINK数据库链接名CONNECT TO 用户名IDENTIFIED BY 密码USING ‘数据库连接字符串’;数据库连接字符串可以用NET8 EASY CONFIG或者直接修改TNSNAMES.ORA里定义.数据库参数global_name=true时要求数据库链接名称跟远端数据库名称一样数据库全局名称可以用以下命令查出SELECT * FROM GLOBAL_NAME;查询远端数据库里的表SELECT …… FROM 表名@数据库链接名;五.权限管理(DCL) 语句1.GRANT 赋于权限常用的系统权限集合有以下三个:CONNECT(基本的连接), RESOURCE(程序开发), DBA(数据库管理)常用的数据对象权限有以下五个:ALL ON 数据对象名, SELECT ON 数据对象名, UPDATE ON 数据对象名, DELETE ON 数据对象名, INSER T ON 数据对象名, AL TER ON 数据对象名GRANT CONNECT, RESOURCE TO 用户名;GRANT SELECT ON 表名 TO 用户名;GRANT SELECT, INSERT, DELETE ON表名 TO 用户名1, 用户名2;2.REVOKE 回收权限REVOKE CONNECT, RESOURCE FROM 用户名;REVOKE SELECT ON 表名FROM 用户名;REVOKE SELECT, INSERT, DELETE ON表名FROM 用户名1, 用户名2;查询数据库中第63号错误:select orgaddr,destaddr from sm_histable0116 where error_code='63';查询数据库中开户用户最大提交和最大下发数:select MSISDN,TCOS,OCOS from ms_usertable;查询数据库中各种错误代码的总和:select error_code,count(*) from sm_histable0513 group by error_code orderby error_code;查询报表数据库中话单统计种类查询。
oracle中查询表记录数的语句
一、介绍在数据库管理系统中,查询表的记录数是一项常见的操作。
对于Oracle数据库来说,查询表的记录数可以通过不同的方法来实现。
本文将从基础的SQL语句到高级SQL语句,以及一些常见的优化技巧,逐步介绍在Oracle数据库中查询表记录数的方法。
二、基础SQL语句1. 使用COUNT函数在Oracle数据库中,最常见的查询表记录数的方法就是使用COUNT 函数。
COUNT函数是SQL中的聚合函数之一,用于计算某一列的行数。
下面是使用COUNT函数查询表记录数的基础语句:```sqlSELECT COUNT(*) FROM table_name;```其中,table_name为需要查询记录数的表名。
2. 使用ROWNUM除了COUNT函数,还可以使用ROWNUM来查询表的记录数。
ROWNUM是Oracle数据库中的一个伪列,用于标识返回的行的行号。
通过查询ROWNUM的最大值,即可得到表的记录数。
以下是使用ROWNUM查询表记录数的语句:```sqlSELECT MAX(ROWNUM) FROM table_name;```这种方法虽然比较简单,但需要注意的是,查询结果可能会受到Oracle的优化影响,因此在某些情况下可能不够准确。
三、高级SQL语句1. 使用DBA_TABLES视图在Oracle数据库中,可以通过DBA_TABLES视图来查询表的记录数。
DBA_TABLES视图是Oracle系统提供的一个系统视图,可以显示数据库中所有表的信息,包括表的记录数。
以下是使用DBA_TABLES视图查询表记录数的语句:```sqlSELECT TABLE_NAME, NUM_ROWS FROM DBA_TABLES WHERE TABLE_NAME = 'table_name';```这种方法可以直接获取表的记录数,无需遍历整个表,因此效率较高。
2. 使用EXPL本人N PLAN除了上述方法,还可以通过使用EXPL本人N PLAN来查询表记录数。
oracle版本的sql语句
【1】Oracle版本的SQL语句【2】Oracle是一个流行的关系型数据库管理系统,其SQL语句是与标准SQL兼容的,但也包含了一些特有的功能和语法。
【3】以下是一些常见的Oracle版本的SQL语句,供大家参考和学习。
【4】查询语句【5】1. 查询所有的列SELECT * FROM table_name;【6】2. 查询指定的列SELECT column1, column2, ... FROM table_name;【7】3. 按条件查询SELECT * FROM table_name WHERE condition;【8】4. 模糊查询SELECT * FROM table_name WHERE column_name LIKE 'value';【9】5. 范围查询SELECT * FROM table_name WHERE column_name BETWEENvalue1 AND value2;【10】6. 排序查询SELECT * FROM table_name ORDER BY column_name;【11】7. 分组查询SELECT column1, COUNT(column2) FROM table_name GROUP BY column1;【12】更新语句【13】1. 更新单个列UPDATE table_name SET column_name = value WHERE condition;【14】2. 更新多个列UPDATE table_name SET column1 = value1, column2 = value2 WHERE condition;【15】删除语句【16】1. 删除指定行DELETE FROM table_name WHERE condition;【17】2. 删除所有行DELETE FROM table_name;【18】插入语句【19】1. 插入单行数据INSERT INTO table_name VALUES (value1, value2, ...);【20】2. 插入多行数据INSERT INTO table_name (column1, column2, ...) VALUES (value1, value2, ...), (value1, value2, ...);【21】子查询【22】1. 单行子查询SELECT column_name FROM table_name WHERE column_name = (SELECT column_name FROM table_name);【23】2. 多行子查询SELECT column_name FROM table_name WHERE column_name IN (SELECT column_name FROM table_name);【24】联合查询【25】1. 内连接SELECT * FROM table1 INNER JOIN table2 ONtable1.column_name = table2.column_name;【26】2. 外连接SELECT * FROM table1 LEFT JOIN table2 ONtable1.column_name = table2.column_name;【27】函数【28】1. 聚合函数SELECT AVG(column_name) FROM table_name;【29】2. 字符函数SELECT UPPER(column_name) FROM table_name;【30】3. 数值函数SELECT ROUND(column_name, n) FROM table_name;【31】4. 日期函数SELECT MONTHS_BETWEEN(date1, date2) FROM table_name;【32】视图【33】1. 创建视图CREATE VIEW view_name AS SELECT column1, column2 FROM table_name WHERE condition;【34】2. 删除视图DROP VIEW view_name;【35】存储过程【36】1. 创建存储过程CREATE PROCEDURE procedure_nameASBEGINsql_statements;END;【37】2. 调用存储过程EXEC procedure_name;【38】以上就是一些常见的Oracle版本的SQL语句,希望对大家有所帮助。
oracle数据库语句汇总
oracle数据库语句汇总在Oracle数据库中,有许多常用的SQL语句可以用于查询、插入、更新和删除数据。
下面列举了一些常见的Oracle数据库语句,以供参考。
1. 查询表中的所有数据:```SELECT * FROM 表名;```2. 查询表中的特定字段数据:```SELECT 字段1, 字段2, ... FROM 表名;```3. 查询表中满足特定条件的数据:```SELECT * FROM 表名 WHERE 条件;```4. 对查询结果进行排序:```SELECT * FROM 表名 ORDER BY 字段 ASC/DESC;```5. 对查询结果进行分组:```SELECT 字段1, 字段2, ... FROM 表名 GROUP BY 字段;```6. 对查询结果进行统计:```SELECT COUNT(*) FROM 表名;```7. 插入数据到表中:```INSERT INTO 表名(字段1, 字段2, ...) VALUES (值1, 值2, ...);```8. 更新表中的数据:```UPDATE 表名 SET 字段1 = 值1, 字段2 = 值2 WHERE 条件;9. 删除表中的数据:```DELETE FROM 表名 WHERE 条件;```10. 创建新表:```CREATE TABLE 表名 (字段1 数据类型,字段2 数据类型,...);```11. 修改表结构:```ALTER TABLE 表名 ADD (字段数据类型); ```12. 删除表:DROP TABLE 表名;```13. 创建索引:```CREATE INDEX 索引名 ON 表名 (字段);```14. 删除索引:```DROP INDEX 索引名;```15. 创建视图:```CREATE VIEW 视图名 AS SELECT * FROM 表名 WHERE 条件; ```16. 删除视图:```DROP VIEW 视图名;17. 创建存储过程:```CREATE PROCEDURE 存储过程名ISBEGIN-- 存储过程的具体逻辑END;```18. 调用存储过程:```EXEC 存储过程名;```以上是一些常见的Oracle数据库语句,可以满足大部分基本的数据操作需求。
oracle 高级sql语句
oracle 高级sql语句Oracle是一种关系型数据库管理系统,提供了丰富的SQL语句用于数据查询、分析和操作。
下面列举了10个符合标题要求的高级SQL语句。
1. 子查询:使用子查询可以将一个查询结果作为另一个查询的条件或数据源。
例如,查询员工表中工资最高的员工所在的部门名称:```sqlSELECT department_nameFROM departmentsWHERE department_id = (SELECT department_idFROM employeesWHERE salary = (SELECT MAX(salary)FROM employees))```2. 联接查询:通过联接查询可以从多个表中获取相关的数据。
例如,查询员工表和部门表,获取每个员工所在部门的名称:```sqlSELECT e.employee_id, e.employee_name, d.department_nameFROM employees eJOIN departments d ON e.department_id = d.department_id```3. 分组查询:使用分组查询可以将数据按照指定的列进行分组,并对每个组进行聚合计算。
例如,查询每个部门的员工数和平均工资:```sqlSELECT department_id, COUNT(*) AS employee_count, AVG(salary) AS average_salaryFROM employeesGROUP BY department_id```4. 排序查询:使用排序查询可以按照指定的列对查询结果进行排序。
例如,查询员工表按照工资从高到低排序:```sqlSELECT employee_id, employee_name, salaryFROM employeesORDER BY salary DESC```5. 窗口函数:窗口函数是一种特殊的函数,用于在查询结果中计算各种统计信息,如排名、累计和偏移等。
oracle sql 语句
oracle sql 语句创建与此标题相符的正文并拓展:Oracle SQL是一种用于管理和处理数据库的强大编程语言。
它被广泛用于各种企业级应用程序和数据库系统中。
Oracle SQL提供了丰富的功能和语法,使开发人员能够执行各种数据库操作,如数据查询、插入、更新和删除等。
在Oracle SQL中,创建数据表是一个非常重要的操作。
通过使用CREATE TABLE语句,可以定义表的结构、字段和约束。
例如,以下是一个创建学生表的示例:CREATE TABLE Students (StudentID NUMBER(10),FirstName VARCHAR2(50),LastName VARCHAR2(50),Age NUMBER(3),Gender CHAR(1),PRIMARY KEY (StudentID));上面的语句创建了一个名为Students的表,包含了StudentID、FirstName、LastName、Age和Gender等字段。
其中,StudentID字段被定义为主键,确保了每个学生都有一个唯一的标识符。
除了创建表,Oracle SQL还提供了各种其他类型的语句,用于插入、更新和删除数据。
例如,以下是一个插入学生数据的示例:INSERT INTO Students (StudentID, FirstName, LastName, Age, Gender)VALUES (1, 'John', 'Doe', 20, 'M');上面的语句将一条新的学生记录插入到Students表中。
此外,Oracle SQL还提供了强大的查询功能,用于检索和过滤数据。
例如,以下是一个查询所有年龄大于等于18岁的学生的示例: SELECT * FROM StudentsWHERE Age >= 18;上面的语句将返回所有满足条件的学生记录。
除了基本的查询语句,Oracle SQL还支持复杂的查询操作,如联接(join)、子查询(subquery)和聚合函数(aggregate function)等。
报表sql语句
报表常用的SQL语句及基本用法报表常用的SQL语句包括SELECT、GROUP BY、ORDER BY等。
下面详细介绍一下它们的基本用法:1. SELECT语句:用于从数据库中筛选数据,并可以指定需要显示的字段。
其基本语法为:SELECT column_name1, column_name2 FROM table_name;其中column_name1和column_name2表示需要显示的字段,table_name表示要查询数据的表名。
如果要查询所有字段,则可以使用*号代替列名。
2. WHERE语句:用于在SQL查询中设置条件,以过滤不必要的数据。
其基本语法为:SELECT column_name FROM table_name WHERE condition;其中condition表示过滤条件,例如column_name = value。
3. GROUP BY语句:用于对查询结果进行分组操作,并且可以进行聚合计算。
其基本语法为:SELECT column_name, aggregate_function(column_name) FROM table_name GROUP BY column_name;其中column_name表示需要分组的字段,aggregate_function是聚合函数(例如SUM、AVG、MAX、MIN等),用于对分组后的数据进行计算。
4. ORDER BY语句:用于对查询结果进行排序操作。
其基本语法为:SELECT column_name FROM table_name ORDER BY column_name ASC(升序)/DESC(降序);其中column_name 表示排序依据的字段。
5. JOIN语句:用于将多张表格组合起来进行查询,并连接表之间的关联字段进行比较。
常见的JOIN类型有INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN等。
oracle中的建表的sql语句
在Oracle数据库中,创建表的SQL语句的基本语法如下:
```sql
CREATE TABLE table_name (
column1 datatype,
column2 datatype,
column3 datatype,
...
);
```
其中:
* `table_name` 是你想要创建的表的名称。
* `column1`, `column2`, `column3` 等是表中的列名。
* `datatype` 是这些列的数据类型,例如VARCHAR2, NUMBER, DATE 等。
例如,如果你想要创建一个名为"Employees" 的表,其中有"ID", "Name", 和"Salary" 三个列,你可以使用以下的SQL语句:
```sql
CREATE TABLE Employees (
ID NUMBER,
Name VARCHAR2(50),
Salary NUMBER(10,2)
);
```
这会创建一个新的表"Employees",其中"ID" 列的数据类型是NUMBER,"Name" 列的数据类型是最大长度为50的VARCHAR2,"Salary" 列的数据类型是带有两位小数的NUMBER。
请注意,这只是创建表的基本语法。
在实际使用中,你可能还需要添加其他的约束,例如PRIMARY KEY、FOREIGN KEY、NOT NULL 等约束来限制列的输入值。
oracle的sql语句
oracle的sql语句Oracle的SQL语句可以用于查询、插入、更新和删除数据库中的数据。
以下是一些常见的Oracle SQL语句示例:1. 查询数据:- 查询所有记录:SELECT * FROM 表名;- 查询指定列:SELECT 列名1, 列名2 FROM 表名;- 带条件查询:SELECT * FROM 表名 WHERE 条件;- 排序查询:SELECT * FROM 表名 ORDER BY 列名ASC/DESC;- 分组查询:SELECT 列名, COUNT(*) FROM 表名GROUP BY 列名;2. 插入数据:- 插入单条记录:INSERT INTO 表名 (列1, 列2) VALUES (值1, 值2);- 插入多条记录:INSERT INTO 表名 (列1, 列2) VALUES (值1, 值2), (值3, 值4), ...;3. 更新数据:- 更新单个字段:UPDATE 表名 SET 列名 = 新值WHERE 条件;- 更新多个字段:UPDATE 表名 SET 列名1 = 新值1, 列名2 = 新值2 WHERE 条件;4. 删除数据:- 删除所有记录:DELETE FROM 表名;- 删除满足条件的记录:DELETE FROM 表名 WHERE 条件;5. 聚合函数:- 计算总数:SELECT COUNT(*) FROM 表名;- 计算平均值:SELECT AVG(列名) FROM 表名;- 计算最大值:SELECT MAX(列名) FROM 表名;- 计算最小值:SELECT MIN(列名) FROM 表名;- 计算求和:SELECT SUM(列名) FROM 表名;这些只是一些常见的Oracle SQL语句示例,实际使用中还可以结合其他语句和函数进行更复杂的查询和操作。
oracle历史sql语句
oracle历史sql语句Oracle是一种流行的关系型数据库管理系统。
它的历史可以追溯到20世纪70年代末和80年代初,当时Oracle公司的创始人之一Larry Ellison开始开发他的第一个数据库产品。
在接下来几十年里,Oracle在数据库技术的领域中一直处于领导地位。
以下是Oracle历史中的一些SQL语句:1. 创建表创建表是在Oracle数据库中存储数据的第一步。
以下是创建一个名为“employees”的表的SQL语句:CREATE TABLE employees (employee_id NUMBER,first_name VARCHAR2(50),last_name VARCHAR2(50),hire_date DATE,job_id VARCHAR2(50),salary NUMBER);2. 插入数据3. 更新数据要更新Oracle数据库中的数据,可以使用UPDATE语句。
以下是将员工号为101的员工的薪水更新为55000的SQL语句:UPDATE employeesSET salary = 55000WHERE employee_id = 101;4. 删除数据5. 查询数据SELECT * FROM employees;6. 添加索引索引可以帮助加快查询数据的速度。
以下是向“employees”表中的“employee_id”列添加索引的SQL语句:CREATE INDEX emp_id_idx ON employees (employee_id);7. 删除索引DROP INDEX emp_id_idx;总之,Oracle是一种功能强大的关系型数据库管理系统,它支持各种SQL语句,可以快速存储、管理、分析和检索大量数据。
oracle查询表结构sql语句
oracle查询表结构sql语句1. 查询表结构的SQL语句在Oracle数据库中,可以使用以下SQL语句查询表的结构信息:1.1. 查询所有表的结构```SELECT owner, table_name, column_name, data_type, data_length, nullableFROM all_tab_columnsORDER BY owner, table_name, column_id;```该语句会返回所有表的所有列的结构信息,包括所属用户(owner)、表名(table_name)、列名(column_name)、数据类型(data_type)、数据长度(data_length)和是否可为空(nullable)等。
1.2. 查询指定表的结构```SELECT column_name, data_type, data_length, nullableFROM all_tab_columnsWHERE owner = 'SCHEMA_NAME' AND table_name = 'TABLE_NAME' ORDER BY column_id;```将上述语句中的'SCHEMA_NAME'替换为要查询表所属的用户,'TABLE_NAME'替换为要查询的表名,可以获取指定表的结构信息。
1.3. 查询表的主键信息```SELECT cols.table_name, cols.column_name, cons.constraint_nameFROM all_constraints cons, all_cons_columns colsWHERE cons.constraint_type = 'P'AND cons.constraint_name = cols.constraint_nameAND cons.owner = cols.ownerAND cols.table_name = 'TABLE_NAME'AND cols.owner = 'SCHEMA_NAME';```将上述语句中的'SCHEMA_NAME'替换为要查询表所属的用户,'TABLE_NAME'替换为要查询的表名,可以获取指定表的主键信息。
ORACLE_50个sql语句
备注:以下语句都已经改成了oracle支持的语句。
不熟的sql:15、查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩???是不是有having的时候就不能用distinct而只能用group by呢???貌似是的说明:以下五十个语句都按照测试数据进行过测试,最好每次只单独运行一个语句。
问题及描述:--1.学生表Student(Sno,Sname,Sage,Ssex) --Sno 学生编号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别--2.课程表Course(Cno,Cname,Tno) --Cno --课程编号,Cname 课程名称,Tno 教师编号--3.教师表Teacher(Tno,Tname) --Tno 教师编号,Tname 教师姓名--4.成绩表SC(Sno,Cno,score) --Sno 学生编号,Cno 课程编号,score 分数*/--创建测试数据create table kxsh.student(sno char(10) primary key not null,sname varchar2(10) not null,ssex char(2) check(ssex in ('男','女')) not null,sage date);insert into kxsh.student values('2008111001','赵雷','男','1990-01-01'); insert into kxsh.student values('2008111002','钱电','男','1990-12-21'); insert into kxsh.student values('2008111003','孙风','男','1990-05-20'); insert into kxsh.student values('2008111004','李云','男','1990-08-06'); insert into kxsh.student values('2008111005','周梅','女','1991-12-01'); insert into kxsh.student values('2008111006','吴兰','女','1992-03-01'); insert into kxsh.student values('2008111007','郑竹','女','1989-07-01'); insert into kxsh.student values('2008111008','王菊','女','1990-01-20');补充1:date包含年月日时分秒,oracle默认格式为’dd-mon月-yy’(dd日子、mon月份、yy 2位的年,如’06-4月-99’ 1999年4月6日)。
oracle语句大全及用法
oracle语句大全及用法Oracle语句是Oracle数据库中用于管理和操作数据的SQL语句。
以下是一些常用的Oracle语句及其用法:1. 数据定义语句(DDL)CREATE DATABASE:用于创建新的数据库。
CREATE TABLE:用于创建新的表。
语法如下:sql`CREATE TABLE table_name (column1 datatype1, column2 datatype2, ...);`ALTER TABLE:用于修改现有的表结构,如添加、删除或修改列。
DROP TABLE:用于删除现有的表。
CREATE INDEX:用于在表上创建索引,以提高查询性能。
2. 数据操纵语句(DML)SELECT:用于从表中查询数据。
语法如下:sql`SELECT column1, column2, ... FROM table_name;`INSERT INTO:用于向表中插入新的数据行。
语法如下:sql`INSERT INTO table_name (column1, column2, ...) VALUES (value1, value2, ...);`UPDATE:用于修改表中的现有数据。
DELETE:用于从表中删除数据。
3. 数据控制语句(DCL)GRANT:用于授予用户或角色对数据库对象的访问权限。
REVOKE:用于撤销用户或角色对数据库对象的访问权限。
4. 事务控制语句(TCL)COMMIT:用于提交当前事务,使所做的更改永久生效。
ROLLBACK:用于撤销当前事务,恢复到事务开始前的状态。
SAVEPOINT:用于在事务中设置保存点,以便在之后的某个时刻可以回滚到该点。
5. 其他常用语句DECLARE:用于声明变量或常量,并为其分配数据类型和初始值。
BEGIN ... END:用于定义PL/SQL代码块的开始和结束。
IF ... THEN ... ELSE:用于条件判断,根据条件执行不同的操作。
经典_Oracle的sql语句百例训练
经典_Oracle的sql语句百例训练oracle系列《一》:简单sql与单行函数使用scott/tiger用户下的emp表和dept表中顺利完成以下练,表的结构表明如下dept部门表(deptno部门编号/dname部门名称/loc地点)工资=薪金+佣金登入oracle数据库1、sqlplusscott/tiger2、sqlplus/nologsql>connscott/tiger若是使用sys的账号进行登录的话,则使用以下语句sql>conn/assysdba【1】emp表中内容查阅sql>select*fromemp;失效,原因就是没找出该表中,因为该表时scott用户的表中,所以查阅时必须加之scott.emp就可以了【2】显示当前用户sql>showuser【3】查看当前用户的所有表sql>select*fromtab;【4】若想重复继续执行上一条sql语句,则在sqlplus命令行下输出\即可【5】查询一张表的结构,例如dept表sql>descdept【6】在雇员表查阅雇员的编号、姓名、工作sql>selectempno,ename,jobfromemp;【7】可以为列名取别名,在linux下oracle如果英文别名不加上双引号则会变成大写sql>selectempno编号,ename姓名,job工作fromemp;【8】查询所有的工作sql>selectdistinctjobfromemp;工作可能会重复,加之distinct关键字【9】若要求按照以下的格式进行结果输出,如no:7469,name:smith,job:clerksql>select'no:'||empno||',name:'||ename||',job:'||jobfromemp;【10】建议列举每个雇员的姓名及年薪【11】查看每月可以得到奖金的雇员信息【12】建议基本工资大于1500,同时可以申领奖金的雇员信息【13】查询基本工资不大于1500,同时不可以领取奖金的雇员信息【14】查阅在1981年雇用的全部雇员信息,between..and涵盖等同于的情况sql>select*fromempwherehiredatebetween'01-jan-81'and'31-dec-81';【15】oracle对大小敏感,所以查询时名字要区分大小写【16】建议查阅出来雇员编号不是7369、7499的雇员信息sql>select*fromempwhereempnonotin(7369,7499);【17】sql中like语句必须特别注意通配符%和_sql>select*fromempwherehiredatelike'?%';【18】查阅雇员编号不是7369的雇员信息,采用<>或!=sql>select*fromempwhereempno<>7369;【19】要求对雇员的工资由低到高进行排序,升序为默认(asc),降序(desc)sql>select*fromempgroupbysal;【20】查阅出来部门号为10的雇员信息,查阅的信息按照工资从低至高,若工资成正比则按雇佣日期从早到晚排序sql>select*fromempwheredeptno=10groupbysaldesc,hiredateasc;数据库系统中,每个数据库之间区别最小的就是在函数的积极支持上,单行函数就是最简单的函数,单行函数分成1、字符函数:接受字符输入并且返回字符或数值2、数值函数:接受数值输入并返回数值3、日期函数:对日期型数据进行操作4、切换函数:将一种数据初始化为另一种数据类型5、通用型函数:nvl、decode函数字符函数:【1】大小写切换upper和lowersql>selectupper('smith')fromdual;【2】将雇员姓名变为开头字母大写,initcapsql>selectinitcap(ename)fromemp;字符函数中存有相连接函数concat,但不如||不好用,除了字符串处置的一些函数字符串撷取:substr()字符串长度:length()内容替代:replace()sql>selectsubstr('hello',1,3),length('hello'),replace('hello','l','x')fromdual;这里注意的是oracle中字符串截取从0和从1开始都是一样的,谨防面试提问【3】建议表明所有雇员的姓名及姓名的后3个字符sql>selectename,substr(ename,length(ename)-2)fromemp;以上操作显得较为麻烦,substr()函数是可以倒着截取sql>selectename,substr(ename,-3,3)fromemp;数值函数:1、四舍五入:round()2、截断小数位:trunc()3、取余(取模):modsql>selectround(789.536)fromdual;【1】保留2位小数,(如果是-2则对整数进行四舍五入,变为800了)sql>selectround(783.56,2)fromdual;【2】使用mod()函数进行取余操作sql>selectmod(10,3)fromdual;日期函数:1、日期-数字=日期2、日期+数字=日期3、日期-日期=数字(天数)【1】求出当前日期sql>selectsysdatefromdual;oracle提供了以下的日期函数支持:months_between():谋出来给定日期范围的月数add_months():在指定日期上加上指定的月数,求出之后的日期next_day():下一个的今天的日期last_day():谋出来给定日期的最后一天日期【2】求出从雇用日期到今天所有雇员的雇员编号、姓名和月数sql>selectempno,ename,round(months_between(sysdate,hiredate))fromemp;。
ORACLE常用SQL语句大全
ORACLE常用SQL语句大全一、基础1、说明:创建数据库CREATE DATABASE database-name2、说明:删除数据库drop database dbname3、说明:备份sql server--- 创建备份数据的 deviceUSE masterEXEC sp_addumpdevice 'disk', 'testBack', 'c:/mssql7backup/MyNwind_1.dat'--- 开始备份BACKUP DATABASE pubs TO testBack4、说明:创建新表create table tabname(col1 type1 [not null] [primary key],col2 type2 [not nul l],..)根据已有的表创建新表:A:select * into table_new from table_old (使用旧表创建新表)B:create table tab_new as select col1,col2… from tab_old definition only<仅适用于Oracle>5、说明:删除表drop table tablename6、说明:增加一个列,删除一个列A:alter table tabname add column col typeB:alter table tabname drop column colname注:DB2DB2中列加上后数据类型也不能改变,唯一能改变的是增加varchar类型的长度。
7、添加主键:Alter table tabname add primary key(col)删除主键:Alter table tabname drop primary key(col)8、创建索引:create [unique] index idxname on tabname(col….)删除索引:drop index idxname注:索引是不可更改的,想更改必须删除重新建。
oracle sql查看表的建表语句
一、概述在使用Oracle数据库时,有时候我们需要查看某张表的建表语句。
这对于了解表的结构以及进行数据库设计和维护工作非常有帮助。
本文将介绍如何使用Oracle SQL语句查看表的建表语句。
二、使用工具在Oracle数据库中,我们可以使用SQL*Plus或者SQL Developer 等工具来执行SQL语句。
这些工具都提供了方便的界面和功能,可用于查询和管理数据库中的对象。
三、查看建表语句的SQL语句要查看表的建表语句,我们可以通过以下SQL语句来实现:```SELECT dbms_metadata.get_ddl('TABLE', 'TABLE_NAME','SCHEMA_NAME')FROM dual;```在这个SQL语句中,我们使用了dbms_metadata.get_ddl函数来获取表的建表语句。
其中,TABLE_NAME是要查看的表的名称,SCHEMA_NAME是表所在的模式名称。
四、示例下面通过一个示例来演示如何使用以上SQL语句来查看表的建表语句。
假设有一个名为EMPLOYEE的表,它存储了员工的基本信息。
我们可以使用以下SQL语句来查看这个表的建表语句:```SELECT dbms_metadata.get_ddl('TABLE', 'EMPLOYEE', 'HR') FROM dual;```其中,'EMPLOYEE'是表的名称,'HR'是表所在的模式名称。
五、注意事项在使用以上SQL语句时,需要注意以下几点:1. 需要有适当的权限来执行dbms_metadata.get_ddl函数。
通常情况下,只有具有DBA权限或者CREATE ANY TABLE权限的用户才能执行该函数。
2. 在执行SQL语句时,需要替换相应的表名称和模式名称。
3. 如果要查看其他类型的对象(如索引、触发器等)的建表语句,可以修改SQL语句中的参数。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
oracle的报表的典型sql语句Select LEAD(m.app_no,(Select Count(1) From app_mtfeature Where app_no='04')-1,'') over(Order By m.app_no) appno,m.feature_seq||'' feature_seq,m.month||'' month,m.pointfee,m.discountFrom app_mtfeature m Where m.app_no='04'Union AllSelect '','合计','',Sum(pointfee),Sum(discount) From app_mtfeature Where app_no='04' Union AllSelect LEAD(m.app_no,(Select Count(1) From app_mtfeature Where app_no='06')-1,'') over(Order By m.app_no) appno,m.feature_seq||'',m.month||'',m.pointfee,m.discountFrom app_mtfeature m Where m.app_no='06'Union AllSelect '','合计','',Sum(pointfee),Sum(discount) From app_mtfeature Where app_no='06' zxbxiaobo@ pwd:xiaobo看看首项,第二项效果怎么样!/blog/34094一些开发脚本(1)./* 根据报表文件名称关键字查找报表的执行文件名称等信息*/SELECT ER_CONCURRENT_PROGRAM_NAME,A.CONCURRENT_PROGRAM_NAME,A.OUTPUT_FILE_TYPE,B.EXECUTION_FILE_NAME,B.EXECUTABLE_NAME,FND_L.MEANING,ER_EXECUTABLE_NAME,B.DESCRIPTIONFROM FND_CONCURRENT_PROGRAMS_VL A,fnd_executables_vl B,FND_LOOKUPS FND_LWHERE A.APPLICATION_ID=B.APPLICATION_IDAND A.EXECUTABLE_ID=B.EXECUTABLE_IDAND B.EXECUTION_METHOD_CODE= FND_L.LOOKUP_CODE(+)AND FND_L.LOOKUP_TYPE='CP_EXECUTION_METHOD_CODE'AND ER_CONCURRENT_PROGRAM_NAME LIKE 'C%杂项出入库报表%'(2)./*查找在标准请求组里提交的报表所在的职责*/SELECT A.RESPONSIBILITY_NAME,ER_CONCURRENT_PROGRAM_NAME,B.CONCURRENT_PROGRA M_NAMEFROM FND_RESPONSIBILITY_VL A,FND_CONCURRENT_PROGRAMS_VL B,FND_REQUEST_GROUP_UNITS CWHERE A.APPLICATION_ID=C.APPLICATION_IDAND A.REQUEST_GROUP_ID=C.REQUEST_GROUP_IDAND B.APPLICATION_ID=C.UNIT_APPLICATION_IDAND B.CONCURRENT_PROGRAM_ID=C.REQUEST_UNIT_IDAND ER_CONCURRENT_PROGRAM_NAME LIKE '%杂项出入库报表%'(3)./*查找在菜单里提交的报表所在职责*/SELECT A.RESPONSIBILITY_NAME,B.PROMPT,ER_CONCURRENT_PROGRAM_NAMEFROM FND_RESPONSIBILITY_VL A,FND_MENU_ENTRIES_VL B,FND_FORM_FUNCTIONS_VL C,FND_REQUEST_GROUPS D,FND_REQUEST_GROUP_UNITS E,FND_CONCURRENT_PROGRAMS_VL FWHERE A.MENU_ID=B.MENU_IDAND B.FUNCTION_ID=C.FUNCTION_IDAND C.PARAMETERS LIKE '%'||D.REQUEST_GROUP_CODE||'%'AND D.APPLICATION_ID=E.APPLICATION_IDAND D.REQUEST_GROUP_ID=E.REQUEST_GROUP_IDAND E.UNIT_APPLICATION_ID=F.APPLICATION_IDAND E.REQUEST_UNIT_ID=F.CONCURRENT_PROGRAM_IDAND ER_CONCURRENT_PROGRAM_NAME LIKE '%杂项出入库报表%'SELECT C.ID_FLEX_NAME,A.ID_FLEX_STRUCTURE_NAME,B.FORM_LEFT_PROMPT,C.APPLICATION_TAB LE_NAME,B.APPLICATION_COLUMN_NAME,B.FLEX_VALUE_SET_IDFROM FND_ID_FLEX_STRUCTURES_VL A,FND_ID_FLEX_SEGMENTS_VL B,FND_ID_FLEXS CWHERE A.ID_FLEX_STRUCTURE_NAME='帐户别名' --用你自己要查的代替,就是Form窗口的标题AND A.APPLICATION_ID=B.APPLICATION_IDAND A.ID_FLEX_CODE=B.ID_FLEX_CODEAND A.ID_FLEX_NUM=B.ID_FLEX_NUMAND A.APPLICATION_ID=C.APPLICATION_IDAND A.ID_FLEX_CODE=C.ID_FLEX_CODE--根据上面FLEX_VALUE_SET_ID查弹性域的数据SELECT *FROM FND_FLEX_VALUES_VL TWHERE T.FLEX_VALUE_SET_ID=1005982 -- FLEX_VALUE_SET_ID--具体某一数据SELECT *FROM FND_FLEX_VALUES_VL TWHERE T.FLEX_VALUE_SET_ID=1005982AND T.FLEX_VALUE='720611'(5)/*根据描述性弹性域的标题查找描述性弹性域表和列*/--SELECT FND_DFV.TITLE,FND_DFV.DESCRIPTIVE_FLEXFIELD_NAME ,FND_DFV.APPLICATION_TABLE_NAME ,FND_DFU.APPLICATION_COLUMN_NAME,FND_DFU.FORM_LEFT_PROMPT,FND_DFU.FORM_ABOVE_PROMPTFROM FND_DESCRIPTIVE_FLEXS_VL FND_DFV,FND_DESCR_FLEX_COL_USAGE_VL FND_DFUWHERE FND_DFV.TITLE='物料' --如:物料AND FND_DFU.DESCRIPTIVE_FLEXFIELD_NAME=FND_DFV.DESCRIPTIVE_FLEXFIELD_NAME(6)。
查找运行请求时间,参数等(可以是某用户的,某个报表)SELECT ER_NAME,papf.full_name,ER_CONCURRENT_PROGRAM_NAME,A.REQUEST_DATE, A.ARGUMENT_TEXT,(A.ACTUAL_COMPLETION_DATE-A.ACTUAL_START_DATE)*24*60 MINUTES, A.ACTUAL_START_DATE,A.ACTUAL_COMPLETION_DATE,a.request_id,a.outfile_nameFROM FND_CONCURRENT_REQUESTS A,FND_CONCURRENT_PROGRAMS_VL B,FND_USER C,per_all_people_f papfWHERE A.CONCURRENT_PROGRAM_ID=B.CONCURRENT_PROGRAM_IDAND A.REQUESTED_BY=ER_IDand er_name=papf.employee_number(+)AND A.ACTUAL_COMPLETION_DATE IS NOT NULLand ER_CONCURRENT_PROGRAM_NAME='你的程序名称' --- like '%XXX%'and er_name=' 你要找的用户的'and a.request_date<=to_date('2005-03-01 23:59:59','yyyy-mm-dd hh24:mi:ss')and a.request_date>=to_date('2005-03-01 00:00:00','yyyy-mm-dd hh24:mi:ss')AND a.request_id> 2254198---为了提高速度,选一个合适时间点的ID2006-12-13sql 调优整理(转载)载自itpub xbxing很好,很全面的一篇关于oracle sql调优的文章。
文章非常长,大家可一有空就看一点。
1. 选用适合的ORACLE优化器ORACLE的优化器共有3种:a. RULE (基于规则)b. COST (基于成本)c. CHOOSE (选择性)设置缺省的优化器,可以通过对init.ora文件中OPTIMIZER_MODE参数的各种声明,如RULE,COST,CHOOSE, ALL_ROWS,FIRST_ROWS . 你当然也在SQL句级或是会话(session)级对其进行覆盖.为了使用基于成本的优化器(CBO, Cost-Based Optimizer) , 你必须经常运行analyze 命令,以增加数据库中的对象统计信息(object statistics)的准确性.如果数据库的优化器模式设置为选择性(CHOOSE),那么实际的优化器模式将和是否运行过analyze命令有关. 如果table已经被analyze过, 优化器模式将自动成为CBO , 反之,数据库将采用RULE形式的优化器.在缺省情况下,ORACLE采用CHOOSE优化器, 为了避免那些不必要的全表扫描(full table scan) , 你必须尽量避免使用CHOOSE优化器,而直接采用基于规则或者基于成本的优化器.2. 访问T able的方式ORACLE 采用两种访问表中记录的方式:a. 全表扫描全表扫描就是顺序地访问表中每条记录. ORACLE采用一次读入多个数据块(database block)的方式优化全表扫描.b. 通过ROWID访问表你可以采用基于ROWID的访问方式情况,提高访问表的效率, , ROWID包含了表中记录的物理位置信息..ORAC LE采用索引(INDEX)实现了数据和存放数据的物理位置(ROWID)之间的联系. 通常索引提供了快速访问ROWID 的方法,因此那些基于索引列的查询就可以得到性能上的提高.3. 共享SQL语句为了不重复解析相同的SQL语句,在第一次解析之后, ORACLE将SQL语句存放在内存中.这块位于系统全局区域SGA(system global area)的共享池(shared buffer pool)中的内存可以被所有的数据库用户共享. 因此,当你执行一个SQL语句(有时被称为一个游标)时,如果它和之前的执行过的语句完全相同, ORACLE就能很快获得已经被解析的语句以及最好的--------------------------------------------------------------------------------txfy 回复于:2003-12-02 10:04:43执行路径. ORACLE的这个功能大大地提高了SQL的执行性能并节省了内存的使用.可惜的是ORACLE只对简单的表提供高速缓冲(cache buffering) ,这个功能并不适用于多表连接查询.数据库管理员必须在init.ora中为这个区域设置合适的参数,当这个内存区域越大,就可以保留更多的语句,当然被共享的可能性也就越大了.当你向ORACLE 提交一个SQL语句,ORACLE会首先在这块内存中查找相同的语句.这里需要注明的是,ORACLE对两者采取的是一种严格匹配,要达成共享,SQL语句必须完全相同(包括空格,换行等).共享的语句必须满足三个条件:A. 字符级的比较:当前被执行的语句和共享池中的语句必须完全相同.例如:SELECT * FROM EMP;和下列每一个都不同SELECT * from EMP;Select * From Emp;SELECT * FROM EMP;B. 两个语句所指的对象必须完全相同:例如:用户对象名如何访问Jack sal_limit private synonymWork_city public synonymPlant_detail public synonymJill sal_limit private synonymWork_city public synonymPlant_detail table owner考虑一下下列SQL语句能否在这两个用户之间共享.SQL 能否共享原因select max(sal_cap) from sal_limit; 不能每个用户都有一个private synonym - sal_limit , 它们是不同的对象select count(*0 from work_city where sdesc like 'NEW%'; 能两个用户访问相同的对象public synon ym - work_cityselect a.sdesc,b.location from work_city a , plant_detail b where a.city_id = b.city_id 不能用户jack 通过private synonym访问plant_detail 而jill 是表的所有者,对象不同.--------------------------------------------------------------------------------txfy 回复于:2003-12-02 10:04:59C. 两个SQL语句中必须使用相同的名字的绑定变量(bind variables)例如:第一组的两个SQL语句是相同的(可以共享),而第二组中的两个语句是不同的(即使在运行时,赋于不同的绑定变量相同的值)a.select pin , name from people where pin = :blk1.pin;select pin , name from people where pin = :blk1.pin;b.select pin , name from people where pin = :blk1.ot_ind;select pin , name from people where pin = :blk1.ov_ind;4. 选择最有效率的表名顺序(只在基于规则的优化器中有效)ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表drivi ng table)将被最先处理. 在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表.当ORA CLE处理多个表时, 会运用排序及合并的方式连接它们.首先,扫描第一个表(FROM子句中最后的那个表)并对记录进行派序,然后扫描第二个表(FROM子句中最后第二个表),最后将所有从第二个表中检索出的记录与第一个表中合适记录进行合并.例如: 表TAB1 16,384 条记录表TAB2 1 条记录选择TAB2作为基础表(最好的方法)select count(*) from tab1,tab2 执行时间0.96秒选择TAB2作为基础表(不佳的方法)--------------------------------------------------------------------------------txfy 回复于:2003-12-02 10:06:03select count(*) from tab2,tab1 执行时间26.09秒如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表.例如: EMP表描述了LOCATION表和CATEGORY表的交集.SELECT *FROM LOCATION L ,CATEGORY C,EMP EWHERE E.EMP_NO BETWEEN 1000 AND 2000AND E.CAT_NO = C.CAT_NOAND E.LOCN = L.LOCN将比下列SQL更有效率SELECT *FROM EMP E ,LOCATION L ,CATEGORY CWHERE E.CAT_NO = C.CAT_NOAND E.LOCN = L.LOCNAND E.EMP_NO BETWEEN 1000 AND 20005. WHERE子句中的连接顺序.ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾.例如:(低效,执行时间156.3秒)SELECT …FROM EMP EWHERE SAL >; 50000AND JOB = …MANAGER‟AND 25 < (SELECT COUNT(*) FROM EMP--------------------------------------------------------------------------------txfy 回复于:2003-12-02 10:06:21WHERE MGR=E.EMPNO);(高效,执行时间10.6秒)SELECT …FROM EMP EWHERE 25 < (SELECT COUNT(*) FROM EMPWHERE MGR=E.EMPNO)AND SAL >; 50000AND JOB = …MANAGER‟;6. SELECT子句中避免使用‘* ‘当你想在SELECT子句中列出所有的COLUMN时,使用动态SQL列引用‘*’是一个方便的方法.不幸的是,这是一个非常低效的方法. 实际上,ORACLE在解析的过程中, 会将’*’依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间.7. 减少访问数据库的次数当执行每条SQL语句时, ORACLE在内部执行了许多工作: 解析SQL语句, 估算索引的利用率, 绑定变量, 读数据块等等. 由此可见, 减少访问数据库的次数, 就能实际上减少ORACLE的工作量.例如,以下有三种方法可以检索出雇员号等于0342或0291的职员.方法1 (最低效)SELECT EMP_NAME , SALARY , GRADEFROM EMPWHERE EMP_NO = 342;SELECT EMP_NAME , SALARY , GRADEFROM EMPWHERE EMP_NO = 291;方法2 (次低效)DECLARECURSOR C1 (E_NO NUMBER) ISSELECT EMP_NAME,SALARY,GRADE--------------------------------------------------------------------------------txfy 回复于:2003-12-02 10:06:58FROM EMPWHERE EMP_NO = E_NO;BEGINOPEN C1(342);FETCH C1 INTO …,..,.. ;OPEN C1(291);FETCH C1 INTO …,..,.. ;CLOSE C1;END;方法3 (高效)SELECT A.EMP_NAME , A.SALARY , A.GRADE,B.EMP_NAME , B.SALARY , B.GRADEFROM EMP A,EMP BWHERE A.EMP_NO = 342AND B.EMP_NO = 291;注意:在SQL*Plus , SQL*Forms和Pro*C中重新设置ARRAYSIZE参数, 可以增加每次数据库访问的检索数据量,建议值为200.8. 使用DECODE函数来减少处理时间使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表.例如:SELECT COUNT(*),SUM(SAL)FROM EMPWHERE DEPT_NO = 0020AND ENAME LIKE‘SMITH%’;SELECT COUNT(*),SUM(SAL)FROM EMPWHERE DEPT_NO = 0030AND ENAME LIKE‘SMITH%’;你可以用DECODE函数高效地得到相同结果SELECT COUNT(DECODE(DEPT_NO,0020,‟X‟,NULL)) D0020_COUNT,COUNT(DECODE(DEPT_NO,0030,‟X‟,NULL)) D0030_COUNT,SUM(DECODE(DEPT_NO,0020,SAL,NULL)) D0020_SAL,SUM(DECODE(DEPT_NO,0030,SAL,NULL)) D0030_SALFROM EMP WHERE ENAME LIKE …SMITH%‟;类似的,DECODE函数也可以运用于GROUP BY 和ORDER BY子句中.9. 整合简单,无关联的数据库访问如果你有几个简单的数据库查询语句,你可以把它们整合到一个查询中(即使它们之间没有关系)例如:SELECT NAMEFROM EMPWHERE EMP_NO = 1234;SELECT NAMEFROM DPTWHERE DPT_NO = 10 ;SELECT NAMEFROM CATWHERE CAT_TYPE = …RD‟;上面的3个查询可以被合并成一个:SELECT , , FROM CAT C , DPT D , EMP E,DUAL XWHERE NVL(…X‟,X.DUMMY) = NVL(…X‟,E.ROWID(+))AND NVL(…X‟,X.DUMMY) = NVL(…X‟,D.ROWID(+))AND NVL(…X‟,X.DUMMY) = NVL(…X‟,C.ROWID(+))AND E.EMP_NO(+) = 1234AND D.DEPT_NO(+) = 10AND C.CAT_TYPE(+) = …RD‟;(译者按: 虽然采取这种方法,效率得到提高,但是程序的可读性大大降低,所以读者还是要权衡之间的利弊)10. 删除重复记录最高效的删除重复记录方法( 因为使用了ROWID)DELETE FROM EMP EWHERE E.ROWID >; (SELECT MIN(X.ROWID)FROM EMP XWHERE X.EMP_NO = E.EMP_NO);11. 用TRUNCATE替代DELETE当删除表中的记录时,在通常情况下, 回滚段(rollback segments ) 用来存放可以被恢复的信息. 如果你没有C OMMIT事务,ORACLE会将数据恢复到删除之前的状态(准确地说是恢复到执行删除命令之前的状况)而当运用TRUNCATE时, 回滚段不再存放任何可被恢复的信息.当命令运行后,数据不能被恢复.因此很少的资源被调用,执行时间也会很短.(译者按: TRUNCATE只在删除全表适用,TRUNCATE是DDL不是DML)12. 尽量多使用COMMIT只要有可能,在程序中尽量多使用COMMIT, 这样程序的性能得到提高,需求也会因为COMMIT所释放的资源而减少:COMMIT所释放的资源:a. 回滚段上用于恢复数据的信息.b. 被程序语句获得的锁c. redo log buffer 中的空间d. ORACLE为管理上述3种资源中的内部花费(译者按: 在使用COMMIT时必须要注意到事务的完整性,现实中效率和事务完整性往往是鱼和熊掌不可得兼) 13. 计算记录条数和一般的观点相反, count(*) 比count(1)稍快, 当然如果可以通过索引检索,对索引列的计数仍旧是最快的. 例如COUNT(EMPNO)(译者按: 在CSDN论坛中,曾经对此有过相当热烈的讨论, 作者的观点并不十分准确,通过实际的测试,上述三种方法并没有显著的性能差别)14. 用Where子句替换HAVING子句避免使用HAVING子句, HAVING 只会在检索出所有记录之后才对结果集进行过滤. 这个处理需要排序,总计等操作. 如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销.例如:低效:SELECT REGION,AVG(LOG_SIZE)FROM LOCATIONGROUP BY REGIONHAVING REGION REGION != …SYDNEY‟AND REGION != …PERTH‟高效SELECT REGION,AVG(LOG_SIZE)FROM LOCATIONWHERE REGION REGION != …SYDNEY‟AND REGION != …PERTH‟GROUP BY REGION(译者按: HAVING 中的条件一般用于对一些集合函数的比较,如COUNT() 等等. 除此而外,一般的条件应该写在WHERE子句中)15. 减少对表的查询在含有子查询的SQL语句中,要特别注意减少对表的查询.例如:低效SELECT TAB_NAMEFROM TABLESWHERE TAB_NAME = ( SELECT TAB_NAMEFROM TAB_COLUMNSWHERE VERSION = 604)AND DB_VER= ( SELECT DB_VERFROM TAB_COLUMNSWHERE VERSION = 604)高效SELECT TAB_NAMEFROM TABLESWHERE (TAB_NAME,DB_VER)= ( SELECT TAB_NAME,DB_VER)FROM TAB_COLUMNSWHERE VERSION = 604)Update 多个Column 例子:低效:UPDATE EMPSET EMP_CAT = (SELECT MAX(CATEGORY) FROM EMP_CATEGORIES),SAL_RANGE = (SELECT MAX(SAL_RANGE) FROM EMP_CATEGORIES)WHERE EMP_DEPT = 0020;高效:UPDATE EMPSET (EMP_CAT, SAL_RANGE)= (SELECT MAX(CATEGORY) , MAX(SAL_RANGE)FROM EMP_CATEGORIES)WHERE EMP_DEPT = 0020;16. 通过内部函数提高SQL效率.SELECT H.EMPNO,E.ENAME,H.HIST_TYPE,T.TYPE_DESC,COUNT(*)FROM HISTORY_TYPE T,EMP E,EMP_HISTORY HWHERE H.EMPNO = E.EMPNOAND H.HIST_TYPE = T.HIST_TYPEGROUP BY H.EMPNO,E.ENAME,H.HIST_TYPE,T.TYPE_DESC;通过调用下面的函数可以提高效率.FUNCTION LOOKUP_HIST_TYPE(TYP IN NUMBER) RETURN VARCHAR2ASTDESC VARCHAR2(30);CURSOR C1 ISSELECT TYPE_DESCFROM HISTORY_TYPEWHERE HIST_TYPE = TYP;BEGINOPEN C1;FETCH C1 INTO TDESC;CLOSE C1;RETURN (NVL(TDESC,‟?‟));END;FUNCTION LOOKUP_EMP(EMP IN NUMBER) RETURN VARCHAR2ASENAME VARCHAR2(30);CURSOR C1 ISSELECT ENAMEFROM EMPWHERE EMPNO=EMP;BEGINOPEN C1;FETCH C1 INTO ENAME;CLOSE C1;RETURN (NVL(ENAME,‟?‟));END;SELECT H.EMPNO,LOOKUP_EMP(H.EMPNO),H.HIST_TYPE,LOOKUP_HIST_TYPE(H.HIST_TYPE),COUNT(*)FROM EMP_HISTORY HGROUP BY H.EMPNO , H.HIST_TYPE;(译者按: 经常在论坛中看到如’能不能用一个SQL写出….’的贴子, 殊不知复杂的SQL往往牺牲了执行效率.能够掌握上面的运用函数解决问题的方法在实际工作中是非常有意义的)17. 使用表的别名(Alias)当在SQL语句中连接多个表时, 请使用表的别名并把别名前缀于每个Column上.这样一来,就可以减少解析的时间并减少那些由Column歧义引起的语法错误.(译者注: Column歧义指的是由于SQL中不同的表具有相同的Column名,当SQL语句中出现这个Column时, SQL解析器无法判断这个Column的归属)18. 用EXISTS替代IN在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接.在这种情况下, 使用EXISTS(或N OT EXISTS)通常将提高查询的效率.低效:SELECT *FROM EMP (基础表)WHERE EMPNO >; 0AND DEPTNO IN (SELECT DEPTNOFROM DEPTWHERE LOC = …MELB‟)高效:SELECT *FROM EMP (基础表)WHERE EMPNO >; 0AND EXISTS (SELECT …X‟FROM DEPTWHERE DEPT.DEPTNO = EMP.DEPTNOAND LOC = …MELB‟)(译者按: 相对来说,用NOT EXISTS替换NOT IN 将更显著地提高效率,下一节中将指出)19. 用NOT EXISTS替代NOT IN在子查询中,NOT IN子句将执行一个内部的排序和合并. 无论在哪种情况下,NOT IN都是最低效的(因为它对子查询中的表执行了一个全表遍历). 为了避免使用NOT IN ,我们可以把它改写成外连接(Outer Joins)或NOT E XISTS.例如:SELECT …FROM EMPWHERE DEPT_NO NOT IN (SELECT DEPT_NOFROM DEPTWHERE DEPT_CAT=‟A‟);为了提高效率.改写为:(方法一: 高效)SELECT ….FROM EMP A,DEPT BWHERE A.DEPT_NO = B.DEPT(+)AND B.DEPT_NO IS NULLAND B.DEPT_CAT(+) = …A‟(方法二: 最高效)SELECT ….FROM EMP EWHERE NOT EXISTS (SELECT …X‟FROM DEPT DWHERE D.DEPT_NO = E.DEPT_NOAND DEPT_CAT = …A‟);20. 用表连接替换EXISTS通常来说, 采用表连接的方式比EXISTS更有效率SELECT ENAMEFROM EMP EWHERE EXISTS (SELECT …X‟FROM DEPTWHERE DEPT_NO = E.DEPT_NOAND DEPT_CAT = …A‟);(更高效)SELECT ENAMEFROM DEPT D,EMP EWHERE E.DEPT_NO = D.DEPT_NOAND DEPT_CAT = …A‟ ;(译者按: 在RBO的情况下,前者的执行路径包括FILTER,后者使用NESTED LOOP)21. 用EXISTS替换DISTINCT当提交一个包含一对多表信息(比如部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT. 一般可以考虑用EXIST替换例如:低效:SELECT DISTINCT DEPT_NO,DEPT_NAMEFROM DEPT D,EMP EWHERE D.DEPT_NO = E.DEPT_NO高效:SELECT DEPT_NO,DEPT_NAMEFROM DEPT DWHERE EXISTS ( SELECT …X‟FROM EMP EWHERE E.DEPT_NO = D.DEPT_NO);EXISTS 使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立刻返回结果.22. 识别’低效执行’的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_TEXTFROM V$SQLAREAWHERE EXECUTIONS>;0AND BUFFER_GETS >; 0AND (BUFFER_GETS-DISK_READS)/BUFFER_GETS < 0.8ORDER BY 4 DESC;(译者按: 虽然目前各种关于SQL优化的图形化工具层出不穷,但是写出自己的SQL工具来解决问题始终是一个最好的方法)--------------------------------------------------------------------------------txfy 回复于:2003-12-02 10:07:3923. 使用TKPROF 工具来查询SQL性能状态SQL trace 工具收集正在执行的SQL的性能状态数据并记录到一个跟踪文件中. 这个跟踪文件提供了许多有用的信息,例如解析次数.执行次数,CPU使用时间等.这些数据将可以用来优化你的系统.设置SQL TRACE在会话级别: 有效ALTER SESSION SET SQL_TRACE TRUE设置SQL TRACE 在整个数据库有效仿, 你必须将SQL_TRACE参数在init.ora中设为TRUE, USER_DUMP_ DEST参数说明了生成跟踪文件的目录(译者按: 这一节中,作者并没有提到TKPROF的用法, 对SQL TRACE的用法也不够准确, 设置SQL TRACE首先要在init.ora中设定TIMED_STATISTICS, 这样才能得到那些重要的时间状态. 生成的trace文件是不可读的,所以要用TKPROF工具对其进行转换,TKPROF有许多执行参数. 大家可以参考ORACLE手册来了解具体的配置. )24. 用EXPLAIN PLAN 分析SQL语句EXPLAIN PLAN 是一个很好的分析SQL语句的工具,它甚至可以在不执行SQL的情况下分析语句. 通过分析,我们就可以知道ORACLE是怎么样连接表,使用什么方式扫描表(索引扫描或全表扫描)以及使用到的索引名称.你需要按照从里到外,从上到下的次序解读分析的结果. EXPLAIN PLAN分析的结果是用缩进的格式排列的, 最内部的操作将被最先解读, 如果两个操作处于同一层中,带有最小操作号的将被首先执行.NESTED LOOP是少数不按照上述规则处理的操作, 正确的执行路径是检查对NESTED LOOP提供数据的操作,其中操作号最小的将被最先处理.译者按:通过实践, 感到还是用SQLPLUS中的SET TRACE 功能比较方便.举例:SQL>; list1 SELECT *2 FROM dept, emp3* WHERE emp.deptno = dept.deptnoSQL>; set autotrace traceonly /*traceonly 可以不显示执行结果*/SQL>; /14 rows selected.Execution Plan----------------------------------------------------------0 SELECT STATEMENT Optimizer=CHOOSE1 0 NESTED LOOPS2 1 TABLE ACCESS (FULL) OF 'EMP'3 1 TABLE ACCESS (BY INDEX ROWID) OF 'DEPT'4 3 INDEX (UNIQUE SCAN) OF 'PK_DEPT' (UNIQUE)Statistics----------------------------------------------------------0 recursive calls2 db block gets30 consistent gets0 physical reads0 redo size2598 bytes sent via SQL*Net to client503 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client0 sorts (memory)0 sorts (disk)14 rows processed通过以上分析,可以得出实际的执行步骤是:1. TABLE ACCESS (FULL) OF 'EMP'2. INDEX (UNIQUE SCAN) OF 'PK_DEPT' (UNIQUE)3. TABLE ACCESS (BY INDEX ROWID) OF 'DEPT'4. NESTED LOOPS (JOINING 1 AND 3)注: 目前许多第三方的工具如TOAD和ORACLE本身提供的工具如OMS的SQL Analyze都提供了极其方便的EXPLAIN PLAN工具.也许喜欢图形化界面的朋友们可以选用它们.25. 用索引提高效率索引是表的一个概念部分,用来提高检索数据的效率. 实际上,ORACLE使用了一个复杂的自平衡B-tree结构. 通常,通过索引查询数据比全表扫描要快. 当ORACLE找出执行查询和Update语句的最佳路径时, ORACLE优化器将使用索引. 同样在联结多个表时使用索引也可以提高效率. 另一个使用索引的好处是,它提供了主键(primary k ey)的唯一性验证.除了那些LONG或LONG RAW数据类型, 你可以索引几乎所有的列. 通常, 在大型表中使用索引特别有效. 当然,你也会发现, 在扫描小表时,使用索引同样能提高效率.虽然使用索引能得到查询效率的提高,但是我们也必须注意到它的代价. 索引需要空间来存储,也需要定期维护, 每当有记录在表中增减或索引列被修改时, 索引本身也会被修改. 这意味着每条记录的IN SERT , DELETE , UPDATE将为此多付出4 , 5 次的磁盘I/O . 因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢.译者按:定期的重构索引是有必要的.ALTER INDEX <INDEXNAME>; REBUILD <TABLESPACENAME>;26. 索引的操作ORACLE对索引有两种访问模式.索引唯一扫描( INDEX UNIQUE SCAN)大多数情况下, 优化器通过WHERE子句访问INDEX.例如:表LODGING有两个索引: 建立在LODGING列上的唯一性索引LODGING_PK和建立在MANAGER列上的非唯一性索引LODGING$MANAGER.SELECT *FROM LODGINGWHERE LODGING = …ROSE HILL‟;在内部, 上述SQL将被分成两步执行, 首先, LODGING_PK 索引将通过索引唯一扫描的方式被访问, 获得相对应的ROWID, 通过ROWID访问表的方式执行下一步检索.如果被检索返回的列包括在INDEX列中,ORACLE将不执行第二步的处理(通过ROWID访问表). 因为检索数据保存在索引中, 单单访问索引就可以完全满足查询结果.下面SQL只需要INDEX UNIQUE SCAN 操作.SELECT LODGINGFROM LODGINGWHERE LODGING = …ROSE HILL‟;索引范围查询(INDEX RANGE SCAN)适用于两种情况:1. 基于一个范围的检索2. 基于非唯一性索引的检索例1:SELECT LODGINGFROM LODGINGWHERE LODGING LIKE …M%‟;WHERE子句条件包括一系列值, ORACLE将通过索引范围查询的方式查询LODGING_PK . 由于索引范围查询将返回一组值, 它的效率就要比索引唯一扫描低一些.例2:SELECT LODGINGFROM LODGINGWHERE MANAGER = …BILL GATES‟;这个SQL的执行分两步, LODGING$MANAGER的索引范围查询(得到所有符合条件记录的ROWID) 和下一步同过ROWID访问表得到LODGING列的值. 由于LODGING$MANAGER是一个非唯一性的索引,数据库不能对它执行索引唯一扫描.由于SQL返回LODGING列,而它并不存在于LODGING$MANAGER索引中, 所以在索引范围查询后会执行一个通过ROWID访问表的操作.WHERE子句中, 如果索引列所对应的值的第一个字符由通配符(WILDCARD)开始, 索引将不被采用.SELECT LODGINGFROM LODGINGWHERE MANAGER LIKE ‘%HANMAN’;在这种情况下,ORACLE将使用全表扫描.27. 基础表的选择基础表(Driving T able)是指被最先访问的表(通常以全表扫描的方式被访问). 根据优化器的不同, SQL语句中基础表的选择是不一样的.如果你使用的是CBO (COST BASED OPTIMIZER),优化器会检查SQL语句中的每个表的物理大小,索引的状态,然后选用花费最低的执行路径.如果你用RBO (RULE BASED OPTIMIZER) , 并且所有的连接条件都有索引对应, 在这种情况下, 基础表就是FROM 子句中列在最后的那个表.举例:SELECT , B.MANAGERFROM WORKER A,LODGING BWHERE A.LODGING = B.LODING;由于LODGING表的LODING列上有一个索引, 而且WORKER表中没有相比较的索引, WORKER表将被作为查询中的基础表.28. 多个平等的索引当SQL语句的执行路径可以使用分布在多个表上的多个索引时, ORACLE会同时使用多个索引并在运行时对它们的记录进行合并, 检索出仅对全部索引有效的记录.在ORACLE选择执行路径时,唯一性索引的等级高于非唯一性索引. 然而这个规则只有当WHERE子句中索引列和常量比较才有效.如果索引列和其他表的索引类相比较. 这种子句在优化器中的等级是非常低的.如果不同表中两个想同等级的索引将被引用, FROM子句中表的顺序将决定哪个会被率先使用. FROM子句中最后的表的索引将有最高的优先级.如果相同表中两个想同等级的索引将被引用, WHERE子句中最先被引用的索引将有最高的优先级.举例:DEPTNO上有一个非唯一性索引,EMP_CAT也有一个非唯一性索引.SELECT ENAME,FROM EMPWHERE DEPT_NO = 20AND EMP_CAT = …A‟;这里,DEPTNO索引将被最先检索,然后同EMP_CAT索引检索出的记录进行合并. 执行路径如下:TABLE ACCESS BY ROWID ON EMPAND-EQUALINDEX RANGE SCAN ON DEPT_IDXINDEX RANGE SCAN ON CAT_IDX29. 等式比较和范围比较当WHERE子句中有索引列, ORACLE不能合并它们,ORACLE将用范围比较.举例:DEPTNO上有一个非唯一性索引,EMP_CAT也有一个非唯一性索引.SELECT ENAMEFROM EMPWHERE DEPTNO >; 20AND EMP_CAT = …A‟;这里只有EMP_CAT索引被用到,然后所有的记录将逐条与DEPTNO条件进行比较. 执行路径如下:TABLE ACCESS BY ROWID ON EMPINDEX RANGE SCAN ON CAT_IDX30. 不明确的索引等级当ORACLE无法判断索引的等级高低差别,优化器将只使用一个索引,它就是在WHERE子句中被列在最前面的. 举例:DEPTNO上有一个非唯一性索引,EMP_CAT也有一个非唯一性索引.SELECT ENAMEFROM EMPWHERE DEPTNO >; 20AND EMP_CAT >; …A‟;这里, ORACLE只用到了DEPT_NO索引. 执行路径如下:TABLE ACCESS BY ROWID ON EMPINDEX RANGE SCAN ON DEPT_IDX译者按:我们来试一下以下这种情况:SQL>; select index_name, uniqueness from user_indexes where table_name = 'EMP';INDEX_NAME UNIQUENES------------------------------ ---------EMPNO UNIQUEEMPTYPE NONUNIQUESQL>; select * from emp where empno >;= 2 and emp_type = 'A' ;no rows selectedExecution Plan----------------------------------------------------------0 SELECT STATEMENT Optimizer=CHOOSE1 0 TABLE ACCESS (BY INDEX ROWID) OF 'EMP'2 1 INDEX (RANGE SCAN) OF 'EMPTYPE' (NON-UNIQUE)虽然EMPNO是唯一性索引,但是由于它所做的是范围比较, 等级要比非唯一性索引的等式比较低!31. 强制索引失效如果两个或以上索引具有相同的等级,你可以强制命令ORACLE优化器使用其中的一个(通过它,检索出的记录数量少) .举例:SELECT ENAMEFROM EMPWHERE EMPNO = 7935AND DEPTNO + 0 = 10 /*DEPTNO上的索引将失效*/AND EMP_TYPE || …‟ = …A‟ /*EMP_TYPE上的索引将失效*/这是一种相当直接的提高查询效率的办法. 但是你必须谨慎考虑这种策略,一般来说,只有在你希望单独优化几个S QL时才能采用它.这里有一个例子关于何时采用这种策略,假设在EMP表的EMP_TYPE列上有一个非唯一性的索引而EMP_CLASS上没有索引.SELECT ENAMEFROM EMPWHERE EMP_TYPE = …A‟AND EMP_CLASS = …X‟;优化器会注意到EMP_TYPE上的索引并使用它. 这是目前唯一的选择. 如果,一段时间以后, 另一个非唯一性建立在EMP_CLASS上,优化器必须对两个索引进行选择,在通常情况下,优化器将使用两个索引并在他们的结果集合上执行排序及合并. 然而,如果其中一个索引(EMP_TYPE)接近于唯一性而另一个索引(EMP_CLASS)上有几千个重复的值. 排序及合并就会成为一种不必要的负担. 在这种情况下,你希望使优化器屏蔽掉EMP_CLASS索引. 用下面的方案就可以解决问题.SELECT ENAMEFROM EMPWHERE EMP_TYPE = …A‟AND EMP_CLASS||‟‟= …X‟;32. 避免在索引列上使用计算.WHERE子句中,如果索引列是函数的一部分.优化器将不使用索引而使用全表扫描.举例:低效:SELECT …FROM DEPTWHERE SAL * 12 >; 25000;高效:SELECT …FROM DEPTWHERE SAL >; 25000/12;译者按:这是一个非常实用的规则,请务必牢记33. 自动选择索引如果表中有两个以上(包括两个)索引,其中有一个唯一性索引,而其他是非唯一性.在这种情况下,ORACLE将使用唯一性索引而完全忽略非唯一性索引.举例:SELECT ENAMEFROM EMPWHERE EMPNO = 2326AND DEPTNO = 20 ;这里,只有EMPNO上的索引是唯一性的,所以EMPNO索引将用来检索记录.TABLE ACCESS BY ROWID ON EMPINDEX UNIQUE SCAN ON EMP_NO_IDX34. 避免在索引列上使用NOT通常,我们要避免在索引列上使用NOT, NOT会产生在和在索引列上使用函数相同的影响. 当ORACLE”遇到”NOT,他就会停止使用索引转而执行全表扫描.举例:低效: (这里,不使用索引)SELECT …FROM DEPTWHERE DEPT_CODE NOT = 0;高效: (这里,使用了索引)SELECT …FROM DEPTWHERE DEPT_CODE >; 0;需要注意的是,在某些时候, ORACLE优化器会自动将NOT转化成相对应的关系操作符. NOT >; to <=NOT >;= to <NOT < to >;=NOT <= to >;译者按:在这个例子中,作者犯了一些错误. 例子中的低效率SQL是不能被执行的.我做了一些测试:SQL>; select * from emp where NOT empno >; 1;no rows selectedExecution Plan----------------------------------------------------------0 SELECT STATEMENT Optimizer=CHOOSE1 0 TABLE ACCESS (BY INDEX ROWID) OF 'EMP'2 1 INDEX (RANGE SCAN) OF 'EMPNO' (UNIQUE)SQL>; select * from emp where empno <= 1;no rows selectedExecution Plan----------------------------------------------------------0 SELECT STATEMENT Optimizer=CHOOSE1 0 TABLE ACCESS (BY INDEX ROWID) OF 'EMP'2 1 INDEX (RANGE SCAN) OF 'EMPNO' (UNIQUE)两者的效率完全一样,也许这符合作者关于”在某些时候, ORACLE优化器会自动将NOT转化成相对应的关系操作符”的观点--------------------------------------------------------------------------------txfy 回复于:2003-12-02 10:08:1535. 用>;=替代>;如果DEPTNO上有一个索引,高效:SELECT *FROM EMPWHERE DEPTNO >;=4低效:SELECT *FROM EMPWHERE DEPTNO >;3两者的区别在于, 前者DBMS将直接跳到第一个DEPT等于4的记录而后者将首先定位到DEPTNO=3的记录并且向前扫描到第一个DEPT大于3的记录.36. 用UNION替换OR (适用于索引列)通常情况下, 用UNION替换WHERE子句中的OR将会起到较好的效果. 对索引列使用OR将造成全表扫描. 注意, 以上规则只针对多个索引列有效. 如果有column没有被索引, 查询效率可能会因为你没有选择OR而降低. 在下面的例子中, LOC_ID 和REGION上都建有索引.高效:SELECT LOC_ID , LOC_DESC , REGIONFROM LOCATIONWHERE LOC_ID = 10UNIONSELECT LOC_ID , LOC_DESC , REGIONFROM LOCATIONWHERE REGION = “MELBOURNE”低效:SELECT LOC_ID , LOC_DESC , REGIONFROM LOCATIONWHERE LOC_ID = 10 OR REGION = “MELBOURNE”如果你坚持要用OR, 那就需要返回记录最少的索引列写在最前面.注意:WHERE KEY1 = 10 (返回最少记录)OR KEY2 = 20 (返回最多记录)ORACLE 内部将以上转换为WHERE KEY1 = 10 AND((NOT KEY1 = 10) AND KEY2 = 20)译者按:下面的测试数据仅供参考: (a = 1003 返回一条记录, b = 1 返回1003条记录)SQL>; select * from unionvsor /*1st test*/2 where a = 1003 or b = 1;1003 rows selected.Execution Plan----------------------------------------------------------0 SELECT STATEMENT Optimizer=CHOOSE1 0 CONCATENATION。