PostRank

2009/05/23

SQL开发建议

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*FormsPro*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只在删除全表适用,TRUNCATEDDL不是DML)
10 尽量多使用COMMIT
只要有可能,在程序中尽量多使用COMMIT, 这样程序的性能得到提高,需求也会因为COMMIT所释放的资源而减少:
COMMIT
所释放的资源:
a.
回滚段上用于恢复数据的信息.
b.
被程序语句获得的锁
c. redo log buffer
中的空间
d. ORACLE
为管理上述3种资源中的内部花费
11 Where子句替换HAVING子句:
避免使用HAVING子句, HAVING 只会在检索出所有记录之后才对结果集进行过滤. 这个处理需要排序,总计等操作. 如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销. (oracle)onwherehaving这三个都可以加条件的子句中,on是最先执行,where次之,having最后,因为on是先把不符合条件的记录过滤后才进行统计,它就可以减少中间运算要处理的数据,按理说应该速度是最快的,where也应该比having快点的,因为它过滤数据后才进行sum,在两个表联接时才用on的,所以在一个表的时候,就剩下wherehaving比较了。在这单表查询统计的情况下,如果要过滤的条件没有涉及到要计算字段,那它们的结果是一样的,只是where可以使用rushmore技术,而having就不能,在速度上后者要慢如果要涉及到计算的字段,就表示在没计算之前,这个字段的值是不确定的,根据上篇写的工作流程,where的作用时间是在计算之前就完成的,而having就是在计算后才起作用的,所以在这种情况下,两者的结果会不同。在多表联接查询时,onwhere更早起作用。系统首先根据各个表之间的联接条件,把多个表合成一个临时表后,再由where进行过滤,然后再计算,计算完后再由having进行过滤。由此可见,要想过滤条件起到正确的作用,首先要明白这个条件应该在什么时候起作用,然后再决定放在那里
12 减少对表的查询:
在含有子查询的SQL语句中,要特别注意减少对表的查询.例子:
SELECT TAB_NAME FROM TABLES WHERE (TAB_NAME,DB_VER) = ( SELECT
TAB_NAME,DB_VER FROM TAB_COLUMNS WHERE VERSION = 604)
13 通过内部函数提高SQL效率.
复杂的SQL往往牺牲了执行效率. 能够掌握上面的运用函数解决问题的方法在实际工作中是非常有意义的
14 使用表的别名(Alias)
当在SQL语句中连接多个表时, 请使用表的别名并把别名前缀于每个Column.这样一来,就可以减少解析的时间并减少那些由Column歧义引起的语法错误.
15 EXISTS替代IN、用NOT EXISTS替代NOT IN
在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接.在这种情况下, 使用EXISTS(NOT EXISTS)通常将提高查询的效率. 在子查询中,NOT IN子句将执行一个内部的排序和合并. 无论在哪种情况下,NOT IN都是最低效的 (因为它对子查询中的表执行了一个全表遍历). 为了避免使用NOT IN ,我们可以把它改写成外连接(Outer Joins)NOT EXISTS.
例子:
(高效)SELECT * FROM EMP (基础表) WHERE EMPNO > 0 AND EXISTS (SELECT 'X' FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = 'MELB')
(
低效)SELECT * FROM EMP (基础表) WHERE EMPNO > 0 AND DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = 'MELB')
16 识别'低效执行'SQL语句:
虽然目前各种关于SQL优化的图形化工具层出不穷,但是写出自己的SQL工具来解决问题始终是一个最好的方法:
SELECT EXECUTIONS , DISK_READS, BUFFER_GETS,
ROUND((BUFFER_GETS-DISK_READS)/BUFFER_GETS,2) Hit_radio,
ROUND(DISK_READS/EXECUTIONS,2) Reads_per_run,
SQL_TEXT
FROM V$SQLAREA
WHERE EXECUTIONS>0
AND BUFFER_GETS > 0
AND (BUFFER_GETS-DISK_READS)/BUFFER_GETS < 0.8
ORDER BY 4 DESC;
17 用索引提高效率:
索引是表的一个概念部分,用来提高检索数据的效率,ORACLE使用了一个复杂的自平衡B-tree结构. 通常,通过索引查询数据比全表扫描要快. ORACLE找出执行查询和Update语句的最佳路径时, ORACLE优化器将使用索引. 同样在联结多个表时使用索引也可以提高效率. 另一个使用索引的好处是,它提供了主键(primary key)的唯一性验证.。那些LONGLONG RAW数据类型, 你可以索引几乎所有的列. 通常, 在大型表中使用索引特别有效. 当然,你也会发现, 在扫描小表时,使用索引同样能提高效率. 虽然使用索引能得到查询效率的提高,但是我们也必须注意到它的代价. 索引需要空间来存储,也需要定期维护, 每当有记录在表中增减或索引列被修改时, 索引本身也会被修改. 这意味着每条记录的INSERT , DELETE , UPDATE将为此多付出4 , 5 次的磁盘I/O . 因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢.。定期的重构索引是有必要的.
ALTER INDEX <INDEXNAME> REBUILD <TABLESPACENAME>
18 EXISTS替换DISTINCT
当提交一个包含一对多表信息(比如部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT. 一般可以考虑用EXIST替换, EXISTS 使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立刻返回结果. 例子:
(
低效):
SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D , EMP E
WHERE D.DEPT_NO = E.DEPT_NO
(
高效):
SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT 'X'
FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO);
19 sql语句用大写的;因为oracle总是先解析sql语句,把小写的字母转换成大写的再执行
20 java代码中尽量少用连接符""连接字符串!
21 避免在索引列上使用NOT 通常, 
我们要避免在索引列上使用NOT, NOT会产生在和在索引列上使用函数相同的影响. ORACLE"遇到"NOT,他就会停止使用索引转而执行全表扫描.
22 避免在索引列上使用计算.
WHERE
子句中,如果索引列是函数的一部分.优化器将不使用索引而使用全表扫描.
举例:
低效:
SELECT … FROM DEPT WHERE SAL * 12 > 25000;
高效:
SELECT … FROM DEPT WHERE SAL > 25000/12;
23 >=替代>
高效:
SELECT * FROM EMP WHERE DEPTNO >=4
低效:
SELECT * FROM EMP WHERE DEPTNO >3
两者的区别在于, 前者DBMS将直接跳到第一个DEPT等于4的记录而后者将首先定位到DEPTNO=3的记录并且向前扫描到第一个DEPT大于3的记录.
24 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, 那就需要返回记录最少的索引列写在最前面.
25 IN来替换OR
这是一条简单易记的规则,但是实际的执行效果还须检验,在ORACLE8i下,两者的执行路径似乎是相同的. 
低效:
SELECT…. FROM LOCATION WHERE LOC_ID = 10 OR LOC_ID = 20 OR LOC_ID = 30
高效
SELECT… FROM LOCATION WHERE LOC_IN IN (10,20,30);
26 避免在索引列上使用IS NULLIS NOT NULL
避免在索引中使用任何可以为空的列,ORACLE将无法使用该索引.对于单列索引,如果列包含空值,索引中将不存在此记录. 对于复合索引,如果每个列都为空,索引中同样不存在此记录. 如果至少有一个列不为空,则记录存在于索引中.举例: 如果唯一性索引建立在表的A列和B列上, 并且表中存在一条记录的A,B值为(123,null) , ORACLE将不接受下一条具有相同A,B值(123,null)的记录(插入). 然而如果所有的索引列都为空,ORACLE将认为整个键值为空而空不等于空. 因此你可以插入1000 条具有相同键值的记录,当然它们都是空! 因为空值不存在于索引列中,所以WHERE子句中对索引列进行空值比较将使ORACLE停用该索引.
低效: (索引失效)
SELECT … FROM DEPARTMENT WHERE DEPT_CODE IS NOT NULL;
高效: (索引有效)
SELECT … FROM DEPARTMENT WHERE DEPT_CODE >=0;
27 总是使用索引的第一个列:
如果索引是建立在多个列上, 只有在它的第一个列(leading column)where子句引用时,优化器才会选择使用该索引. 这也是一条简单而重要的规则,当仅引用索引的第二个列时,优化器使用了全表扫描而忽略了索引
28 UNION-ALL 替换UNION ( 如果有可能的话)
SQL语句需要UNION两个查询结果集合时,这两个结果集合会以UNION-ALL的方式被合并, 然后在输出最终结果前进行排序. 如果用UNION ALL替代UNION, 这样排序就不是必要了. 效率就会因此得到提高. 需要注意的是,UNION ALL 将重复输出两个结果集合中相同记录. 因此各位还是要从业务需求分析使用UNION ALL的可行性. UNION 将对结果集合排序,这个操作会使用到SORT_AREA_SIZE这块内存. 对于这块内存的优化也是相当重要的. 下面的SQL可以用来查询排序的消耗量
低效:
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = '31-DEC-95'
UNION
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = '31-DEC-95'
高效:
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = '31-DEC-95'
UNION ALL
SELECT ACCT_NUM, BALANCE_AMT
FROM DEBIT_TRANSACTIONS
WHERE TRAN_DATE = '31-DEC-95'
29 WHERE替代ORDER BY
ORDER BY
子句只在两种严格的条件下使用索引.
ORDER BY
中所有的列必须包含在相同的索引中并保持在索引中的排列顺序.
ORDER BY
中所有的列必须定义为非空.
WHERE
子句使用的索引和ORDER BY子句中所使用的索引不能并列.
例如:
DEPT包含以下列:
DEPT_CODE PK NOT NULL
DEPT_DESC NOT NULL
DEPT_TYPE NULL
低效: (索引不被使用)
SELECT DEPT_CODE FROM DEPT ORDER BY DEPT_TYPE
高效: (使用索引)
SELECT DEPT_CODE FROM DEPT WHERE DEPT_TYPE > 0
30 避免改变索引列的类型.:
当比较不同数据类型的数据时, 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 WHERETO_NUMBER(EMP_TYPE)=123
因为内部发生的类型转换, 这个索引将不会被用到! 为了避免ORACLE对你的SQL进行隐式的类型转换, 最好把类型转换用显式表现出来. 注意当字符和数值比较时, ORACLE会优先转换数值类型到字符类型
31 需要当心的WHERE子句:
某些SELECT 语句中的WHERE子句不使用索引. 这里有一些例子.
在下面的例子里, (1)'!=' 将不使用索引. 记住, 索引只能告诉你什么存在于表中, 而不能告诉你什么不存在于表中. (2) '||'是字符连接函数. 就象其他函数那样, 停用了索引. (3) '+'是数学函数. 就象其他数学函数那样, 停用了索引. (4)相同的索引列不能互相比较,这将会启用全表扫描.
32 a. 如果检索数据量超过30%的表中记录数.使用索引将没有显著的效率提高.
b.
在特定情况下, 使用索引也许会比全表扫描慢, 但这是同一个数量级上的区别. 而通常情况下,使用索引比全表扫描要块几倍乃至几千倍!
33 避免使用耗费资源的操作:
带有DISTINCT,UNION,MINUS,INTERSECT,ORDER BYSQL语句会启动SQL引擎
执行耗费资源的排序(SORT)功能. DISTINCT需要一次排序操作, 而其他的至少需要执行两次排序. 通常, 带有UNION, MINUS , INTERSECTSQL语句都可以用其他方式重写. 如果你的数据库的SORT_AREA_SIZE调配得好, 使用UNION , MINUS, INTERSECT也是可以考虑的, 毕竟它们的可读性很强
34 优化GROUP BY:
提高GROUP BY 语句的效率, 可以通过将不需要的记录在GROUP BY 之前过滤掉.下面两个查询返回相同结果但第二个明显就快了许多.
低效:
SELECT JOB , AVG(SAL)
FROM EMP
GROUP JOB
HAVING JOB = 'PRESIDENT'
OR JOB = 'MANAGER'
高效:
SELECT JOB , AVG(SAL)
FROM EMP
WHERE JOB = 'PRESIDENT'
OR JOB = 'MANAGER'
GROUP JOB

 

 

 

Oracle 常見問題集

摘自:網路
 
Oracle 常見問題集

  1. Oracle安裝完成後的初始口令
  internal/oracle
  sys/change_on_install
  system/manager
  scott/tiger
  sysman/oem_temp
  2. ORACLE9IAS WEB CACHE的初始默認用戶和密碼?
  administrator/administrator
  3. oracle 8.0.5怎麽創建資料庫
  用orainst。如果有motif介面,可以用orainst /m
  4. oracle 8.1.7怎麽創建資料庫
  dbassist
  5. oracle 9i 怎麽創建資料庫
  dbca
  6. oracle中的裸設備指的是什麽
  裸設備就是繞過文件系統直接訪問的儲存空間
  7. oracle如何區分 64-bit/32bit 版本???
  $ sqlplus '/ AS SYSDBA'
  SQL*Plus: Release 9.0.1.0.0 - Production on Mon Jul 14 17:01:09
  2003
  (c) Copyright 2001 Oracle Corporation. All rights reserved.
  Connected to:
  Oracle9i Enterprise Edition Release 9.0.1.0.0 - Production
  With the Partitioning option
  JServer Release 9.0.1.0.0 - Production
  SQL> select * from v$version;
  BANNER
  ----------------------------------------------------------------
  Oracle9i Enterprise Edition Release 9.0.1.0.0 - Production
  PL/SQL Release 9.0.1.0.0 - Production
  CORE 9.0.1.0.0 Production
  TNS for Solaris: Version 9.0.1.0.0 - Production
  NLSRTL Version 9.0.1.0.0 - Production
  SQL>
  8. SVRMGR什麽意思?
  svrmgrl,Server Manager.
  9i下沒有,已經改爲用SQLPLUS了
  sqlplus /nolog
  變爲歸檔日誌型的
  9. 請問如何分辨某個用戶是從哪台機器登陸ORACLE的
  SELECT machine , terminal FROM V$SESSION;
  10. 用什麽語句查詢欄位呢?
  desc table_name 可以查詢表的結構
  select field_name,... from ... 可以查詢欄位的值
  select * from all_tables where table_name like '%'
  select * from all_tab_columns where table_name=' '
  11. 怎樣得到觸發器、過程、函數的創建腳本?
  desc user_source
  user_triggers
  12. 怎樣計算一個表佔用的空間的大小?
  select owner,table_name,
  NUM_ROWS,
  BLOCKS*AAA/1024/1024 "Size M",
  EMPTY_BLOCKS,
  LAST_ANALYZED
  from dba_tables
  where table_name='XXX';
  Here: AAA is the value of db_block_size ;
  XXX is the table name you want to check
  13. 如何查看最大會話數?
  SELECT * FROM V$PARAMETER WHERE NAME LIKE 'proc%';
  SQL>
  SQL> show parameter processes
  NAME TYPE VALUE
  ------------------------------------ -------
  ------------------------------
  aq_tm_processes integer 1
  db_writer_processes integer 1
  job_queue_processes integer 4
  log_archive_max_processes integer 1
  processes integer 200
  這裏爲200個用戶。
  select * from v$license;
  其中sessions_highwater紀錄曾經到達的最大會話數
  14. 如何查看系統被鎖的事務時間?
  select * from v$locked_object ;
  15. 如何以archivelog的方式運行oracle。
  init.ora
  log_archive_start = true
  RESTART DATABASE
  16. 怎麽獲取有哪些用戶在使用資料庫
  select username from v$session;
  17. 資料表中的欄位最大數是多少
  表或視圖中的最大列數爲 1000
  18. 怎樣查得資料庫的SID
  select name from v$database;
  也可以直接查看 init.ora文件
  19. 如何在Oracle伺服器上通過SQLPLUS查看本機IP位址
  select sys_context('userenv','ip_address') from dual;
  如果是登陸本機資料庫,只能返回127.0.0.1,呵呵
  20. unix 下怎麽調整資料庫的時間?
  su -root
  date -u 08010000
  21. 在ORACLE TABLE中如何抓取MEMO類型欄位為空的資料記錄
  select remark from oms_flowrec where trim(' ' from remark) is not
  null ;
  22. 如何用BBB表的資料去更新AAA表的資料(有關聯的欄位)
  UPDATE AAA SET BNS_SNM=(SELECT BNS_SNM FROM BBB WHERE
  AAA.DPT_NO=BBB.DPT_NO) WHERE BBB.DPT_NO IS NOT NULL;
  23. P4電腦安裝方法
  將SYMCJIT.DLL改為SYSMCJIT.OLD
  24. 何查詢SERVER是不是OPS
  SELECT * FROM V$OPTION;
  如果PARALLEL SERVER=TRUE則有OPS能
  25. 何查詢每個用戶的權限
  SELECT * FROM DBA_SYS_PRIVS;
  26. 如何將表移動表空間
  ALTER TABLE TABLE_NAME MOVE TABLESPACE_NAME;
  27. 如何將索引移動表空間
  ALTER INDEX INDEX_NAME REBUILD TABLESPACE TABLESPACE_NAME;
  28. 在LINUX,UNIX下如何啟動DBA STUDIO
  OEMAPP DBASTUDIO
  29. 查詢鎖的狀況的對象有
  V$LOCK, V$LOCKED_OBJECT, V$SESSION, V$SQLAREA, V$PROCESS ;
  查詢鎖的表的方法:
  SELECT S.SID SESSION_ID, S.USERNAME, DECODE(LMODE, 0, 'None', 1,
  'Null', 2, 'Row-S (SS)', 3, 'Row-X (SX)', 4, 'Share', 5, 'S/Row-X
  (SSX)', 6, 'Exclusive', TO_CHAR(LMODE)) MODE_HELD, DECODE(REQUEST,
  0, 'None', 1, 'Null', 2, 'Row-S (SS)', 3, 'Row-X (SX)', 4,
  'Share', 5, 'S/Row-X (SSX)', 6, 'Exclusive', TO_CHAR(REQUEST))
  MODE_REQUESTED, O.OWNER||'.'||O.OBJECT_NAME||'
  ('||O.OBJECT_TYPE||')', S.TYPE LOCK_TYPE, L.ID1 LOCK_ID1, L.ID2
  LOCK_ID2 FROM V$LOCK L, SYS.DBA_OBJECTS O, V$SESSION S WHERE L.SID
  = S.SID AND L.ID1 = O.OBJECT_ID ;
  30. 如何解鎖
  ALTER SYSTEM KILL SESSION 'SID,SERIR#';
  31. SQLPLUS下如何修改編輯器
  DEFINE _EDITOR="<編輯器的完整路經>" -- 必須加上雙引號
  來定義新的編輯器,也可以把這個寫在$ORACLE_HOME/sqlplus/admin/glogin.sql裏面使它永久有效。
  32. ORACLE產生隨機函數是
  DBMS_RANDOM.RANDOM
  33. LINUX下查詢磁盤競爭狀況命令
  Sar -d
  33. LINUX下查詢CPU競爭狀況命令
  sar -r
  34. 查詢當前用戶對象
  SELECT * FROM USER_OBJECTS;
  SELECT * FROM DBA_SEGMENTS;
  35. 如何獲取錯誤資訊
  SELECT * FROM USER_ERRORS;
  36. 如何獲取鏈接狀況
  SELECT * FROM DBA_DB_LINKS;
  37. 查看數據庫字元狀況
  SELECT * FROM NLS_DATABASE_PARAMETERS;
  SELECT * FROM V$NLS_PARAMETERS;
  38. 查詢表空間資訊
  SELECT * FROM DBA_DATA_FILES;
  39. ORACLE的INTERAL用戶要口令
  修改 SQLNET.ORA
  SQLNET.AUTHENTICATION_SERVICES=(NTS)
  40. 出現JAVA.EXE的解決辦法
  一般是將ORACLEORAHOMEXIHTTPSERVER改成手工啟動可以的
  X是8或9
  41. 如何給表、列加注釋?
  SQL>comment on table 表 is '表注釋';
  注釋已創建。
  SQL>comment on column 表.列 is '列注釋';
  注釋已創建。
  SQL> select * from user_tab_comments where comments is not null;
  42. 如何查看各個表空間佔用磁片情況?
  SQL> col tablespace format a20
  SQL> select
  b.file_id 文件ID號,
  b.tablespace_name 表空間名,
  b.bytes 位元組數,
  (b.bytes-sum(nvl(a.bytes,0))) 已使用,
  sum(nvl(a.bytes,0)) 剩餘空間,
  sum(nvl(a.bytes,0))/(b.bytes)*100 剩餘百分比
  from dba_free_space a,dba_data_files b
  where a.file_id=b.file_id
  group by b.tablespace_name,b.file_id,b.bytes
  order by b.file_id
  43. 如把ORACLE設置爲MTS或專用模式?
  #dispatchers="(PROTOCOL=TCP) (SERVICE=SIDXDB)"
  加上就是MTS,注釋就是專用模式,SID是指你的實例名。
  44. 如何才能得知系統當前的SCN號
  select max(ktuxescnw * power(2, 32) + ktuxescnb) from x$ktuxe;
  45. 請問如何在ORACLE中取毫秒
  9i之前不支援,9i開始有timestamp.
  9i可以用select systimestamp from dual;
  大家在應用ORACLE的時候可能會遇到很多看起來不難的問題, 特別對新手來說, 今天我簡單把它總結一下, 發布給大家,
  希望對大家有幫助! 和大家一起探討, 共同進步!
  對ORACLE高手來說是不用看的.
  46. 如何在字串里加回車?
  select 'Welcome to visit'||chr(10)||'www.CSDN.NET' from dual ;
  47. 中文是如何排序的?
  Oracle9i之前,中文是按照二進位編碼進行排序的。
  在oracle9i中新增了按照拼音、部首、筆畫排序功能。設置NLS_SORT值
  SCHINESE_RADICAL_M 按照部首(第一順序)、筆劃(第二順序)排序
  SCHINESE_STROKE_M 按照筆劃(第一順序)、部首(第二順序)排序
  SCHINESE_PINYIN_M 按照拼音排序
  48. Oracle8i中物件名可以用中文嗎?
  可以
  49. 如何改變WIN中SQL*Plus啓動選項?
  SQL*PLUS自身的選項設置我們可以在$ORACLE_HOME/sqlplus/admin/glogin.sql中設置。
  50. 怎樣修改oracel資料庫的默認日期
  alter session set nls_date_format='yyyymmddhh24miss';
  OR
  可以在init.ora中加上一行
  nls_date_format='yyyymmddhh24miss'
  51. 如何將小表放入keep池中
  alter table xxx storage(buffer_pool keep);
  52. 如何檢查是否安裝了某個patch
  check that oraInventory
  53. 如何使select語句使查詢結果自動生成序號
  select rownum,COL from table;
  54. 如何知道資料褲中某個表所在的tablespace
  select tablespace_name from user_tables where table_name='TEST';
  select * from user_tables中有個欄位TABLESPACE_NAME,(oracle);
  select * from dba_segments where …;
  55. 怎麽可以快速做一個和原表一樣的備份表
  create table new_table as (select * from old_table);
  55. 怎麽在sqlplus下修改procedure
  select line,trim(text) t from user_source where name ='A' order by
  line;
  56. 怎樣解除PROCEDURE被意外鎖定
  alter system kill session ,把那個session給殺掉,不過你要先查出她的session id
  or
  把該過程重新改個名字就可以了。
  57. SQL Reference是個什麽東西?
  是一本sql的使用手冊,包括語法、函數等等,oracle官方網站的文檔中心有下載.
  58. 如何查看資料庫的狀態
  unix下
  ps -ef | grep ora
  windows下
  看服務是否起來
  是否可以連上資料庫
  59. 請問如何修改一張表的主鍵
  alter table aaa
  drop constraint aaa_key ;
  alter table aaa
  add constraint aaa_key primary key(a1,b1) ;
  60. 改變資料檔案的大小
  用 ALTER DATABASE .... DATAFILE .... ;
  手工改變資料檔案的大小,對於原來的 資料檔案有沒有損害。
  61. 怎樣查看ORACLE中有哪些程式在運行之中?
  查看v$sessions表
  62. 怎麽可以看到資料庫有多少個tablespace
  select * from dba_tablespaces;
  63. 如何修改oracle資料庫的用戶連接數?
  修改initSID.ora,將process加大,重啓資料庫.
  64. 如何查出一條記錄的最後更新時間
  可以用logminer 察看
  65. 如何在PL/SQL中讀寫文件?
  UTL_FILE包允許用戶通過PL/SQL讀寫作業系統文件。
  66. 怎樣把"&"放入一條記錄中?
  insert into a values (translate ('at{&}t','at{}','at'));
  67. EXP如何加QUERY參數?
  EXP USER/PASS FILE=A.DMP TABLES(BSEMPMS)
  QUERY='"WHERE EMP_NO=\'S09394\'\" ﹔
  68. 關於oracle8i支援簡體和繁體的字元集問題?
  ZHS16GBK可以支
  69. Data Guard是什麽軟體?
  就是Standby的換代産品
  70. 如何創建SPFILE
  SQL> connect / as sysdba
  SQL> select * from v$version;
  SQL> create pfile from spfile;
  SQL> CREATE SPFILE FROM
  PFILE='E:\ora9i\admin\eygle\pfile\init.ora';
  文件已創建。
  SQL> CREATE SPFILE='E:\ora9i\database\SPFILEEYGLE.ORA' FROM
  PFILE='E:\ora9i\admin\eygle\pfile\init.ora';
  文件已創建。
 71. 內核參數的應用
  shmmax
  含義:這個設置並不決定究竟Oracle資料庫或者作業系統使用多少實體記憶體,只決定了最多可以使用的記憶體數目。這個設置也不影響作業系統的內核資源。
  設置方法:0.5*實體記憶體
  例子:Set shmsys:shminfo_shmmax=10485760
  shmmin
  含義:共用記憶體的最小大小。
  設置方法:一般都設置成爲1。
  例子:Set shmsys:shminfo_shmmin=1:
  shmmni
  含義:系統中共用記憶體段的最大個數。
  例子:Set shmsys:shminfo_shmmni=100
  shmseg
  含義:每個用戶進程可以使用的最多的共用記憶體段的數目。
  例子:Set shmsys:shminfo_shmseg=20:
  semmni
  含義:系統中semaphore identifierer的最大個數。
  設置方法:把這個變數的值設置爲這個系統上的所有Oracle的實例的init.ora中的最大的那個processes的那個值加10。
  例子:Set semsys:seminfo_semmni=100
  semmns
  含義:系統中emaphores的最大個數。
  設置方法:這個值可以通過以下方式計算得到:各個Oracle實例的initSID.ora裏邊的processes的值的總和(除去最大的Processes參數)+最大的那個Processes×2+10×Oracle實例的個數。
  例子:Set semsys:seminfo_semmns=200
  semmsl:
  含義:一個set中semaphore的最大個數。
  設置方法:設置成爲10+所有Oracle實例的InitSID.ora中最大的Processes的值。
  例子:Set semsys:seminfo_semmsl=-200
  72. 怎樣查看哪些用戶擁有SYSDBA、SYSOPER許可權?
  SQL>conn sys/change_on_install
  SQL>select * from V_$PWFILE_USERS;
  73. 如何單獨備份一個或多個表?
  exp 用戶/密碼 tables=(表1,…,表2)
  74. 如何單獨備份一個或多個用戶?
  exp system/manager owner=(用戶1,用戶2,…,用戶n) file=導出文件
  75. 如何對CLOB欄位進行全文檢索?
  SELECT * FROM A WHERE dbms_lob.instr(a.a,'K',1,1)>0;
  76. 如何顯示當前連接用戶
  SHOW USER
  77. 如何查看資料檔案放置的路徑
  col file_name format a50
  SQL> select tablespace_name,file_id,bytes/1024/1024,file_name from
  dba_data_files order by file_id;
  78. 如何查看現有回滾段及其狀態
  SQL> col segment format a30
  SQL> SELECT
  SEGMENT_NAME,OWNER,TABLESPACE_NAME,SEGMENT_ID,FILE_ID,STATUS FROM
  DBA_ROLLBACK_SEGS
  79. 如何改變一個欄位初始定義的Check範圍?
  SQL> alter table xxx drop constraint constraint_name;
  之後再創建新約束:
  SQL> alter table xxx add constraint constraint_name check();
  80. Oracle常用系統文件有哪些?
  通過以下視圖顯示這些文件資訊:v$database,v$datafile,v$logfile v$controlfile
  v$parameter;
  81. 內連接INNER JOIN
  Select a.* from bsempms a,bsdptms b where a.dpt_no=b.dpt_no;
  82. 如何外連接
  Select a.* from bsempms a,bsdptms b where a.dpt_no=b.dpt_no(+);
  Select a.* from bsempms a,bsdptms b wherea.dpt_no(+)=b.dpt_no;
  83. 如何執行腳本SQL文件
  SQL>@$PATH/filename.sql;
  84. 如何快速清空一個大表
  SQL>truncate table table_name;
  85. 如何查有多少個數據庫實例
  SQL>SELECT * FROM V$INSTANCE;
  86. 如何查詢數據庫有多少表
  SQL>select * from all_tables;
  87. 如何測試SQL語句執行所用的時間
  SQL>set timing on ;
  SQL>select * from tablename;
  大家在應用ORACLE的時候可能會遇到很多看起來不難的問題, 特別對新手來說, 今天我簡單把它總結一下, 發布給大家,
  希望對大家有幫助! 和大家一起探討, 共同進步!
  對ORACLE高手來說是不用看的.
  88. CHR()的反函數是
  ASCII()
  SELECT CHAR(65) FROM DUAL;
  SELECT ASCII('A') FROM DUAL;
  89. 字串的連接
  SELECT CONCAT(COL1,COL2) FROM TABLE ;
  SELECT COL1||COL2 FROM TABLE ;
  90. 怎麽把select出來的結果導到一個文字檔案中?
  SQL>SPOOL C:\ABCD.TXT;
  SQL>select * from table;
  SQL >spool off;
  91. 怎樣估算SQL執行的I/O數
  SQL>SET AUTOTRACE ON ;
  SQL>SELECT * FROM TABLE;
  OR
  SQL>SELECT * FROM v$filestat ;
  可以查看IO數
  92. 如何在sqlplus下改變欄位大小
  alter table table_name modify (field_name varchar2(100));
  改大行,改小不行(除非都是空的)
  93. 如何查詢某天的資料
  select * from table_name where
  trunc(日期欄位)=to_date('2003-05-02','yyyy-mm-dd');
  94. sql 語句如何插入全年日期?
  create table BSYEAR (d date);
  insert into BSYEAR
  select to_date('20030101','yyyymmdd')+rownum-1
  from all_objects
  where rownum <= to_char(to_date('20031231','yyyymmdd'),'ddd');
  95. 如果修改表名
  alter table old_table_name rename to new_table_name;
  96. 如何取得命令的返回狀態值?
  sqlcode=0
  97. 如何知道用戶擁有的許可權
  SELECT * FROM dba_sys_privs ;
  98. 從網上下載的ORACLE9I與市場上賣的標準版有什麽區別?
  從功能上說沒有區別,只不過oracle公司有明文規定;從網站上下載的oracle産品不得用於 商業用途,否則侵權。
  99. 怎樣判斷資料庫是運行在歸檔模式下還是運行在非歸檔模式下?
  進入dbastudio,歷程--〉資料庫---〉歸檔查看。
  100. sql>startup pfile和ifile,spfiled有什麽區別?
  pfile就是Oracle傳統的初始化參數文件,文本格式的。
  ifile類似於c語言裏的include,用於把另一個文件引入
  spfile是9i裏新增的並且是默認的參數文件,二進位格式
  startup後應該只可接pfile
  101. 如何搜索出前N條記錄?
  SELECT * FROM empLOYEE WHERE ROWNUM < n
  ORDER BY empno;
  102. 如何知道機器上的Oracle支援多少並發用戶數
  SQL>conn internal ;
  SQL>show parameter processes ;
  103. db_block_size可以修改嗎
  一般不可以﹐不建議這樣做的。
  104. 如何統計兩個表的記錄總數
  select (select count(id) from aa)+(select count(id) from bb) 總數
  from dual;
  105. 怎樣用Sql語句實現查找一列中第N大值?
  select * from
  (select t.*,dense_rank() over (order by sal) rank from employee)
  where rank = N;
  106. 如何在給現有的日期加上2年?(
  select add_months(sysdate,24) from dual;
  107. USED_UBLK爲負值表示什麽意思
  It is "harmless".
  108. Connect string是指什麽
  應該是tnsnames.ora中的服務名後面的內容
  109. 怎樣擴大REDO LOG的大小?
  建立一個臨時的redolog組,然後切換日誌,刪除以前的日誌,建立新的日誌。
  110. tablespace 是否不能大於4G
  沒有限制.
  111. 返回大於等於N的最小整數值
  SELECT CEIL(N) FROM DUAL;
  112. 返回小於等於N的最小整數值
  SELECT FLOOR(N) FROM DUAL;
  113. 返回當前月的最後一天
  SELECT LAST_DAY(SYSDATE) FROM DUAL;
  114. 如何不同用戶間數據導入
  IMP SYSTEM/MANAGER FILE=AA.DMP FROMUSER=USER_OLD TOUSER=USER_NEW
  ROWS=Y INDEXES=Y ;
  115. 如何找資料庫表的主鍵欄位的名稱
  SQL>SELECT * FROM user_constraints WHERE CONSTRAINT_TYPE='P' and
  table_name='TABLE_NAME';
  116. 兩個結果集互加的函數
  SQL>SELECT * FROM BSEMPMS_OLD INTERSECT SELECT * FROM BSEMPMS_NEW;
  SQL>SELECT * FROM BSEMPMS_OLD UNION SELECT * FROM BSEMPMS_NEW;
  SQL>SELECT * FROM BSEMPMS_OLD UNION ALL SELECT * FROM BSEMPMS_NEW;
  117. 兩個結果集互減的函數
  SQL>SELECT * FROM BSEMPMS_OLD MINUS SELECT * FROM BSEMPMS_NEW;
  118. 如何配置Sequence
  建sequence seq_custid
  create sequence seq_custid start 1 incrememt by 1;
  建表時:
  create table cust
  { cust_id smallint not null,
  ...}
  insert 時:
  insert into table cust
  values( seq_cust.nextval, ...)
  日期的各部分的常用的的寫法
  119>.取時間點的年份的寫法:
  SELECT TO_CHAR(SYSDATE,'YYYY') FROM DUAL;
  120>.取時間點的月份的寫法:
  SELECT TO_CHAR(SYSDATE,'MM') FROM DUAL;
  121>.取時間點的日的寫法:
  SELECT TO_CHAR(SYSDATE,'DD') FROM DUAL;
  122>.取時間點的時的寫法:
  SELECT TO_CHAR(SYSDATE,'HH24') FROM DUAL;
  123>.取時間點的分的寫法:
  SELECT TO_CHAR(SYSDATE,'MI') FROM DUAL;
  124>.取時間點的秒的寫法:
  SELECT TO_CHAR(SYSDATE,'SS') FROM DUAL;
  125>.取時間點的日期的寫法:
  SELECT TRUNC(SYSDATE) FROM DUAL;
  126>.取時間點的時間的寫法:
  SELECT TO_CHAR(SYSDATE,'HH24:MI:SS') FROM DUAL;
  127>.日期,時間形態變為字元形態
  SELECT TO_CHAR(SYSDATE) FROM DUAL;
  128>.將字串轉換成日期或時間形態:
  SELECT TO_DATE('2003/08/01') FROM DUAL;
  129>.返回參數的星期幾的寫法:
  SELECT TO_CHAR(SYSDATE,'D') FROM DUAL;
  130>.返回參數一年中的第幾天的寫法:
  SELECT TO_CHAR(SYSDATE,'DDD') FROM DUAL;
  131>.返回午夜和參數中指定的時間值之間的秒數的寫法:
  SELECT TO_CHAR(SYSDATE,'SSSSS') FROM DUAL;
  132>.返回參數中一年的第幾周的寫法:
  SELECT TO_CHAR(SYSDATE,'WW') FROM DUAL;
  大家在應用ORACLE的時候可能會遇到很多看起來不難的問題, 特別對新手來說, 今天我簡單把它總結一下, 發布給大家,
  希望對大家有幫助! 和大家一起探討, 共同進步!
  對ORACLE高手來說是不用看的.
  虛擬欄位
  133. CURRVAL 和 nextval
  爲表創建序列
  CREATE SEQUENCE EMPSEQ ... ;
  SELECT empseq.currval FROM DUAL ;
  自動插入序列的數值
  INSERT INTO emp
  VALUES (empseq.nextval, 'LEWIS', 'CLERK',
  7902, SYSDATE, 1200, NULL, 20) ;
  134. ROWNUM
  按設定排序的行的序號
  SELECT * FROM emp WHERE ROWNUM < 10 ;
  135. ROWID
  返回行的物理位址
  SELECT ROWID, ename FROM emp WHERE deptno = 20 ;
  136. 將N秒轉換爲時分秒格式?
  set serverout on
  declare
  N number := 1000000;
  ret varchar2(100);
  begin
  ret := trunc(n/3600) || '小時' ||
  to_char(to_date(mod(n,3600),'sssss'),'fmmi"分 "ss"秒"') ;
  dbms_output.put_line(ret);
  end;
  137. 如何查詢做比較大的排序的進程?
  SELECT b.tablespace, b.segfile#, b.segblk#, b.blocks, a.sid,
  a.serial#,
  a.username, a.osuser, a.status
  FROM v$session a,v$sort_usage b
  WHERE a.saddr = b.session_addr
  ORDER BY b.tablespace, b.segfile#, b.segblk#, b.blocks ;
  138. 如何查詢做比較大的排序的進程的SQL語句?
  select /*+ ORDERED */ sql_text from v$sqltext a
  where a.hash_value = (
  select sql_hash_value from v$session b
  where b.sid = &sid and b.serial# = &serial)
  order by piece asc ;
  139. 如何查找重復記錄?
  SELECT * FROM TABLE_NAME
  WHERE ROWID!=(SELECT MAX(ROWID) FROM TABLE_NAME D
  WHERE TABLE_NAME.COL1=D.COL1 AND TABLE_NAME.COL2=D.COL2);
  140. 如何刪除重復記錄?
  DELETE FROM TABLE_NAME
  WHERE ROWID!=(SELECT MAX(ROWID) FROM TABLE_NAME D
  WHERE TABLE_NAME.COL1=D.COL1 AND TABLE_NAME.COL2=D.COL2);
  141. 如何快速編譯所有視圖?
  SQL >SPOOL VIEW1.SQL
  SQL >SELECT 'ALTER VIEW '||TNAME||'
  COMPILE;' FROM TAB;
  SQL >SPOOL OFF
  然後執行VIEW1.SQL即可。
  SQL >@VIEW1.SQL;
  142. ORA-01555 SNAPSHOT TOO OLD的解決辦法
  增加MINEXTENTS的值,增加區的大小,設置一個高的OPTIMAL值。
  143. 事務要求的回滾段空間不夠,表現爲表空間用滿(ORA-01560錯誤),回滾段擴展到達參數
  MAXEXTENTS的值(ORA-01628)的解決辦法.
  向回滾段表空間添加文件或使已有的文件變大;增加MAXEXTENTS的值。
  144. 如何加密ORACLE的存儲過程?
  下列存儲過程內容放在AA.SQL文件中
  create or replace procedure testCCB(i in number) as
  begin
  dbms_output.put_line('輸入參數是'||to_char(i));
  end;
  SQL>wrap iname=a.sql;
  PL/SQL Wrapper: Release 8.1.7.0.0 - Production on Tue Nov 27
  22:26:48 2001
  Copyright (c) Oracle Corporation 1993, 2000. All Rights Reserved.
  Processing AA.sql to AA.plb
  運行AA.plb
  SQL> @AA.plb ;
  145. 如何監控事例的等待?
  select event,sum(decode(wait_Time,0,0,1)) "Prev",
  sum(decode(wait_Time,0,1,0)) "Curr",count(*) "Tot"
  from v$session_Wait
  group by event order by 4;
  146. 如何回滾段的爭用情況?
  select name, waits, gets, waits/gets "Ratio"
  from v$rollstat C, v$rollname D
  where C.usn = D.usn;
  147. 如何監控表空間的 I/O 比例?
  select B.tablespace_name name,B.file_name "file",A.phyrds pyr,
  A.phyblkrd pbr,A.phywrts pyw, A.phyblkwrt pbw
  from v$filestat A, dba_data_files B
  where A.file# = B.file_id
  order by B.tablespace_name;
  148. 如何監控文件系統的 I/O 比例?
  select substr(C.file#,1,2) "#", substr(C.name,1,30) "Name",
  C.status, C.bytes, D.phyrds, D.phywrts
  from v$datafile C, v$filestat D
  where C.file# = D.file#;
  149. 如何在某個用戶下找所有的索引?
  select user_indexes.table_name,
  user_indexes.index_name,uniqueness, column_name
  from user_ind_columns, user_indexes
  where user_ind_columns.index_name = user_indexes.index_name
  and user_ind_columns.table_name = user_indexes.table_name
  order by user_indexes.table_type, user_indexes.table_name,
  user_indexes.index_name, column_position;
  150. 如何監控 SGA 的命中率?
  select a.value + b.value "logical_reads", c.value "phys_reads",
  round(100 * ((a.value+b.value)-c.value) / (a.value+b.value))
  "BUFFER HIT RATIO"
  from v$sysstat a, v$sysstat b, v$sysstat c
  where a.statistic# = 38 and b.statistic# = 39
  and c.statistic# = 40;
 151. 如何監控 SGA 中字典緩衝區的命中率?
  select parameter, gets,Getmisses , getmisses/(gets+getmisses)*100
  "miss ratio",
  (1-(sum(getmisses)/ (sum(gets)+sum(getmisses))))*100 "Hit ratio"
  from v$rowcache
  where gets+getmisses <>0
  group by parameter, gets, getmisses;
  152. 如何監控 SGA 中共用緩存區的命中率,應該小於1% ?
  select sum(pins) "Total Pins", sum(reloads) "Total Reloads",
  sum(reloads)/sum(pins) *100 libcache
  from v$librarycache;
  select sum(pinhits-reloads)/sum(pins) "hit
  radio",sum(reloads)/sum(pins) "reload percent"
  from v$librarycache;
  153. 如何顯示所有資料庫物件的類別和大小?
  select count(name) num_instances ,type ,sum(source_size)
  source_size ,
  sum(parsed_size) parsed_size ,sum(code_size) code_size
  ,sum(error_size) error_size,
  sum(source_size) +sum(parsed_size) +sum(code_size)
  +sum(error_size) size_required
  from dba_object_size
  group by type order by 2;
  154. 監控 SGA 中重做日誌緩存區的命中率,應該小於1%
  SELECT name, gets, misses, immediate_gets, immediate_misses,
  Decode(gets,0,0,misses/gets*100) ratio1,
  Decode(immediate_gets+immediate_misses,0,0,
  immediate_misses/(immediate_gets+immediate_misses)*100) ratio2
  FROM v$latch WHERE name IN ('redo allocation', 'redo copy');
  155. 監控記憶體和硬碟的排序比率,最好使它小於 .10,增加 sort_area_size
  SELECT name, value FROM v$sysstat WHERE name IN ('sorts (memory)',
  'sorts (disk)');
  156. 如何監控當前資料庫誰在運行什麽SQL語句?
  SELECT osuser, username, sql_text from v$session a, v$sqltext b
  where a.sql_address =b.address order by address, piece;
  157. 如何監控字典緩衝區?
  SELECT (SUM(PINS - RELOADS)) / SUM(PINS) "LIB CACHE" FROM
  V$LIBRARYCACHE;
  SELECT (SUM(GETS - GETMISSES - USAGE - FIXED)) / SUM(GETS) "ROW
  CACHE" FROM V$ROWCACHE;
  SELECT SUM(PINS) "EXECUTIONS", SUM(RELOADS) "CACHE MISSES WHILE
  EXECUTING" FROM V$LIBRARYCACHE;
  後者除以前者,此比率小於1%,接近0%爲好。
  SELECT SUM(GETS) "DICTIONARY GETS",SUM(GETMISSES) "DICTIONARY
  CACHE GET MISSES"
  FROM V$ROWCACHE
  158. 監控 MTS
  select busy/(busy+idle) "shared servers busy" from v$dispatcher;
  此值大於0.5時,參數需加大
  select sum(wait)/sum(totalq) "dispatcher waits" from v$queue where
  type='dispatcher';
  select count(*) from v$dispatcher;
  select servers_highwater from v$mts;
  servers_highwater接近mts_max_servers時,參數需加大
  159. 如何知道當前用戶的ID號
  SQL>SHOW USER;
  OR
  SQL>select user from dual;
  160. 如何查看碎片程度高的表
  SELECT segment_name table_name , COUNT(*) extents
  FROM dba_segments WHERE owner NOT IN ('SYS', 'SYSTEM') GROUP BY
  segment_name
  HAVING COUNT(*) = (SELECT MAX( COUNT(*) ) FROM dba_segments GROUP
  BY segment_name);
  162. 如何知道表在表空間中的存儲情況
  select segment_name,sum(bytes),count(*) ext_quan from dba_extents
  where
  tablespace_name='&tablespace_name' and segment_type='TABLE' group
  by tablespace_name,segment_name;
  163. 如何知道索引在表空間中的存儲情況
  select segment_name,count(*) from dba_extents where
  segment_type='INDEX' and owner='&owner'
  group by segment_name;
  164、如何知道使用CPU多的用戶session
  11是cpu used by this session
  select a.sid,spid,status,substr(a.program,1,40)
  prog,a.terminal,osuser,value/60/100 value
  from v$session a,v$process b,v$sesstat c
  where c.statistic#=11 and c.sid=a.sid and a.paddr=b.addr order by
  value desc;
  165. 如何知道監聽器日誌文件
  以8I爲例
  $ORACLE_HOME/NETWORK/LOG/LISTENER.LOG
  166. 如何知道監聽器參數文件
  以8I爲例
  $ORACLE_HOME/NETWORK/ADMIN/LISTENER.ORA
  167. 如何知道TNS 連接文件
  以8I爲例
  $ORACLE_HOME/NETWORK/ADMIN/TNSNAMES.ORA
  168. 如何知道Sql*Net 環境文件
  以8I爲例
  $ORACLE_HOME/NETWORK/ADMIN/SQLNET.ORA
  169. 如何知道警告日誌文件
  以8I爲例
  $ORACLE_HOME/ADMIN/SID/BDUMP/SIDALRT.LOG
  170. 如何知道基本結構
  以8I爲例
  $ORACLE_HOME/RDBMS/ADMIN/STANDARD.SQL
  171. 如何知道建立資料字典視圖
  以8I爲例
  $ORACLE_HOME/RDBMS/ADMIN/CATALOG.SQL
  172. 如何知道建立審計用資料字典視圖
  以8I爲例
  $ORACLE_HOME/RDBMS/ADMIN/CATAUDIT.SQL
  173. 如何知道建立快照用資料字典視圖
  以8I爲例
  $ORACLE_HOME/RDBMS/ADMIN/CATSNAP.SQL
  本講主要講的是SQL語句的優化方法! 主要基於ORACLE9I的.
  174. /*+ALL_ROWS*/
  表明對語句塊選擇基於開銷的優化方法,並獲得最佳吞吐量,使資源消耗最小化.
  例如:
  SELECT /*+ALL+_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE
  EMP_NO='CCBZZP';
  175. /*+FIRST_ROWS*/
  表明對語句塊選擇基於開銷的優化方法,並獲得最佳回應時間,使資源消耗最小化.
  例如:
  SELECT /*+FIRST_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE
  EMP_NO='CCBZZP';
  176. /*+CHOOSE*/
  表明如果資料字典中有訪問表的統計資訊,將基於開銷的優化方法,並獲得最佳的吞吐量;
  表明如果資料字典中沒有訪問表的統計資訊,將基於規則開銷的優化方法;
  例如:
  SELECT /*+CHOOSE*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE
  EMP_NO='CCBZZP';
  177. /*+RULE*/
  表明對語句塊選擇基於規則的優化方法.
  例如:
  SELECT /*+ RULE */ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE
  EMP_NO='CCBZZP';
  178. /*+FULL(TABLE)*/
  表明對表選擇全局掃描的方法.
  例如:
  SELECT /*+FULL(A)*/ EMP_NO,EMP_NAM FROM BSEMPMS A WHERE
  EMP_NO='CCBZZP';
  179. /*+ROWID(TABLE)*/
  提示明確表明對指定表根據ROWID進行訪問.
  例如:
  SELECT /*+ROWID(BSEMPMS)*/ * FROM BSEMPMS WHERE
  ROWID>='AAAAAAAAAAAAAA'
  AND EMP_NO='CCBZZP';
  180. /*+CLUSTER(TABLE)*/
  提示明確表明對指定表選擇簇掃描的訪問方法,它只對簇物件有效.
  例如:
  SELECT /*+CLUSTER */ BSEMPMS.EMP_NO,DPT_NO FROM BSEMPMS,BSDPTMS
  WHERE DPT_NO='TEC304' AND BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
  181. /*+INDEX(TABLE INDEX_NAME)*/
  表明對表選擇索引的掃描方法.
  例如:
  SELECT /*+INDEX(BSEMPMS SEX_INDEX) USE SEX_INDEX BECAUSE THERE ARE
  FEWMALE BSEMPMS */ FROM BSEMPMS WHERE SEX='M';
  182. /*+INDEX_ASC(TABLE INDEX_NAME)*/
  表明對表選擇索引昇冪的掃描方法.
  例如:
  SELECT /*+INDEX_ASC(BSEMPMS PK_BSEMPMS) */ FROM BSEMPMS WHERE
  DPT_NO='CCBZZP';
  183. /*+INDEX_COMBINE*/
  爲指定表選擇點陣圖訪問路經,如果INDEX_COMBINE中沒有提供作爲參數的索引,將選擇出點陣圖索引的
  布林組合方式.
  例如:
  SELECT /*+INDEX_COMBINE(BSEMPMS SAL_BMI HIREDATE_BMI)*/ * FROM
  BSEMPMS
  WHERE SAL<5000000 AND HIREDATE<SYSDATE;< SPAN>
  184. /*+INDEX_JOIN(TABLE INDEX_NAME)*/
  提示明確命令優化器使用索引作爲訪問路徑.
  例如:
  SELECT /*+INDEX_JOIN(BSEMPMS SAL_HMI HIREDATE_BMI)*/ SAL,HIREDATE
  FROM BSEMPMS WHERE SAL<60000;
  185. /*+INDEX_DESC(TABLE INDEX_NAME)*/
  表明對表選擇索引降冪的掃描方法.
  例如:
  SELECT /*+INDEX_DESC(BSEMPMS PK_BSEMPMS) */ FROM BSEMPMS WHERE
  DPT_NO='CCBZZP';
  186. /*+INDEX_FFS(TABLE INDEX_NAME)*/
  對指定的表執行快速全索引掃描,而不是全表掃描的辦法.
  例如:
  SELECT /*+INDEX_FFS(BSEMPMS IN_EMPNAM)*/ * FROM BSEMPMS WHERE
  DPT_NO='TEC305';
  187. /*+ADD_EQUAL TABLE INDEX_NAM1,INDEX_NAM2,...*/
  提示明確進行執行規劃的選擇,將幾個單列索引的掃描合起來.
  例如:
  SELECT /*+INDEX_FFS(BSEMPMS IN_DPTNO,IN_EMPNO,IN_SEX)*/ * FROM
  BSEMPMS WHERE EMP_NO='CCBZZP' AND DPT_NO='TDC306';
  188. /*+USE_CONCAT*/
  對查詢中的WHERE後面的OR條件進行轉換爲UNION ALL的組合查詢.
  例如:
  SELECT /*+USE_CONCAT*/ * FROM BSEMPMS WHERE DPT_NO='TDC506' AND
  SEX='M';
  189. /*+NO_EXPAND*/
  對於WHERE後面的OR 或者IN-LIST的查詢語句,NO_EXPAND將阻止其基於優化器對其進行擴展.
  例如:
  SELECT /*+NO_EXPAND*/ * FROM BSEMPMS WHERE DPT_NO='TDC506' AND
  SEX='M';
  190. /*+NOWRITE*/
  禁止對查詢塊的查詢重寫操作.
  191. /*+REWRITE*/
  可以將視圖作爲參數.
  192. /*+MERGE(TABLE)*/
  能夠對視圖的各個查詢進行相應的合併.
  例如:
  SELECT /*+MERGE(V) */ A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS A
  (SELET DPT_NO
  ,AVG(SAL) AS AVG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE
  A.DPT_NO=V.DPT_NO
  AND A.SAL>V.AVG_SAL;
  193. /*+NO_MERGE(TABLE)*/
  對於有可合併的視圖不再合併.
  例如:
  SELECT /*+NO_MERGE(V) */ A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS
  A (SELET DPT_NO
  ,AVG(SAL) AS AVG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE
  A.DPT_NO=V.DPT_NO
  AND A.SAL>V.AVG_SAL;
  194. /*+ORDERED*/
  根據表出現在FROM中的順序,ORDERED使ORACLE依此順序對其連接.
  例如:
  SELECT /*+ORDERED*/ A.COL1,B.COL2,C.COL3 FROM TABLE1 A,TABLE2
  B,TABLE3 C
  WHERE A.COL1=B.COL1 AND B.COL1=C.COL1;
  195. /*+USE_NL(TABLE)*/
  將指定表與嵌套的連接的行源進行連接,並把指定表作爲內部表.
  例如:
  SELECT /*+ORDERED USE_NL(BSEMPMS)*/
  BSDPTMS.DPT_NO,BSEMPMS.EMP_NO,BSEMPMS.EMP_NAM FROM BSEMPMS,BSDPTMS
  WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
  196. /*+USE_MERGE(TABLE)*/
  將指定的表與其他行源通過合併排序連接方式連接起來.
  例如:
  SELECT /*+USE_MERGE(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS
  WHERE
  BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
  197. /*+USE_HASH(TABLE)*/
  將指定的表與其他行源通過哈希連接方式連接起來.
  例如:
  SELECT /*+USE_HASH(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS WHERE
  BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
  198. /*+DRIVING_SITE(TABLE)*/
  強制與ORACLE所選擇的位置不同的表進行查詢執行.
  例如:
  SELECT /*+DRIVING_SITE(DEPT)*/ * FROM BSEMPMS,DEPT@BSDPTMS WHERE
  BSEMPMS.DPT_NO=DEPT.DPT_NO;
  199. /*+LEADING(TABLE)*/
  將指定的表作爲連接次序中的首表.
  200. /*+CACHE(TABLE)*/
  當進行全表掃描時,CACHE提示能夠將表的檢索塊放置在緩衝區緩存中最近最少列表LRU的最近使用端
  例如:
  SELECT /*+FULL(BSEMPMS) CAHE(BSEMPMS) */ EMP_NAM FROM BSEMPMS;
  201. /*+NOCACHE(TABLE)*/
  當進行全表掃描時,CACHE提示能夠將表的檢索塊放置在緩衝區緩存中最近最少列表LRU的最近使用端
  例如:
  SELECT /*+FULL(BSEMPMS) NOCAHE(BSEMPMS) */ EMP_NAM FROM BSEMPMS;
  202. /*+APPEND*/
  直接插入到表的最後,可以提高速度.
  insert /*+append*/ into test1 select * from test4 ;
  203. /*+NOAPPEND*/
  通過在插入語句生存期內停止並行模式來啓動常規插入.
  insert /*+noappend*/ into test1 select * from test4 ;
  ORACLE優化器
  . 選用適合的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. 訪問Table的方式
  ORACLE 採用兩種訪問表中記錄的方式:
  a. 全表掃描
  全表掃描就是順序地訪問表中每條記錄. ORACLE採用一次讀入多個資料塊(database block)的方式優化全表掃描.
  b. 通過ROWID訪問表
  你可以採用基於ROWID的訪問方式情況,提高訪問表的效率, ,
  ROWID包含了表中記錄的物理位置資訊..ORACLE採用索引(INDEX)實現了資料和存放資料的物理位置(ROWID)之間的聯繫.
  通常索引提供了快速訪問ROWID的方法,因此那些基於索引列的查詢就可以得到性能上的提高.
  3. 共用SQL語句
  爲了不重復解析相同的SQL語句,在第一次解析之後, ORACLE將SQL語句存放在記憶體中.這塊位於系統全局區域SGA(system
  global area)的共用池(shared buffer pool)中的記憶體可以被所有的資料庫用戶共用.
  因此,當你執行一個SQL語句(有時被稱爲一個游標)時,如果它
  和之前的執行過的語句完全相同, ORACLE就能很快獲得已經被解析的語句以及最好的
  執行路徑. 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 synonym
  Work_city public synonym
  Plant_detail public synonym
  Jill sal_limit private synonym
  Work_city public synonym
  Plant_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 synonym - work_city
  select a.sdesc,b.location from work_city a , plant_detail b where
  a.city_id = b.city_id
  不能
  用戶jack 通過private synonym訪問plant_detail 而jill 是表的所有者,物件不同.
  C. 兩個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子句中寫在最後的表(基礎表 driving
  table)將被最先處理. 在FROM子句中包含多個表的情況下,你必須選擇記錄條數最少的表作爲基礎表.當ORACLE處理多個表時,
  會運用排序及合併的方式連接它們.首先,掃描第一個表(FROM子句中最後的那個表)並對記錄進行派序,然後掃描第二個表(FROM子句中最後第二個表),最後將所有從第二個表中檢索出的記錄與第一個表中合適記錄進行合併.
  例如:
  表 TAB1 16,384 條記錄
  表 TAB2 1 條記錄
  選擇TAB2作爲基礎表 (最好的方法)
  select count(*) from tab1,tab2 執行時間0.96秒
  選擇TAB2作爲基礎表 (不佳的方法)
  select count(*) from tab2,tab1 執行時間26.09秒
  如果有3個以上的表連接查詢, 那就需要選擇交叉表(intersection table)作爲基礎表,
  交叉表是指那個被其他表所引用的表.
  例如:
  EMP表描述了LOCATION表和CATEGORY表的交集.
  SELECT *
  FROM LOCATION L ,
  CATEGORY C,
  EMP E
  WHERE E.EMP_NO BETWEEN 1000 AND 2000
  AND E.CAT_NO = C.CAT_NO
  AND E.LOCN = L.LOCN
  將比下列SQL更有效率
  SELECT *
  FROM EMP E ,
  LOCATION L ,
  CATEGORY C
  WHERE E.CAT_NO = C.CAT_NO
  AND E.LOCN = L.LOCN
  AND E.EMP_NO BETWEEN 1000 AND 2000
  5. WHERE子句中的連接順序.
  ORACLE採用自下而上的順序解析WHERE子句,根據這個原理,表之間的連接必須寫在其他WHERE條件之前,
  那些可以過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾.
  例如:
  (低效,執行時間156.3秒)
  SELECT …
  FROM EMP E
  WHERE SAL > 50000
  AND JOB = 'MANAGER'
  AND 25 < (SELECT COUNT(*) FROM EMP
  WHERE MGR=E.EMPNO);
  (高效,執行時間10.6秒)
  SELECT …
  FROM EMP E
  WHERE 25 < (SELECT COUNT(*) FROM EMP
  WHERE MGR=E.EMPNO)
  AND SAL > 50000
  AND JOB = 'MANAGER';
  6. SELECT子句中避免使用 ' * '
  當你想在SELECT子句中列出所有的COLUMN時,使用動態SQL列引用 '*'
  是一個方便的方法.不幸的是,這是一個非常低效的方法. 實際上,ORACLE在解析的過程中, 會將'*' 依次轉換成所有的列名,
  這個工作是通過查詢資料字典完成的, 這意味著將耗費更多的時間.
  7. 減少訪問資料庫的次數
  當執行每條SQL語句時, ORACLE在內部執行了許多工作: 解析SQL語句, 估算索引的利用率, 綁定變數 , 讀資料塊等等.
  由此可見, 減少訪問資料庫的次數 , 就能實際上減少ORACLE的工作量.
  例如,
  以下有三種方法可以檢索出雇員號等於0342或0291的職員.
  方法1 (最低效)
  SELECT EMP_NAME , SALARY , GRADE
  FROM EMP
  WHERE EMP_NO = 342;
  SELECT EMP_NAME , SALARY , GRADE
  FROM EMP
  WHERE EMP_NO = 291;
  方法2 (次低效)
  DECLARE
  CURSOR C1 (E_NO NUMBER) IS
  SELECT EMP_NAME,SALARY,GRADE
  FROM EMP
  WHERE EMP_NO = E_NO;
  BEGIN
  OPEN 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.GRADE
  FROM EMP A,EMP B
  WHERE A.EMP_NO = 342
  AND B.EMP_NO = 291;
  注意:
  在SQL*Plus , SQL*Forms和Pro*C中重新設置ARRAYSIZE參數, 可以增加每次資料庫訪問的檢索資料量
  ,建議值爲200
  8. 使用DECODE函數來減少處理時間
  使用DECODE函數可以避免重復掃描相同記錄或重復連接相同的表.
  例如:
  SELECT COUNT(*),SUM(SAL)
  FROMEMP
  WHERE DEPT_NO = 0020
  AND ENAME LIKE'SMITH%';
  SELECT COUNT(*),SUM(SAL)
  FROMEMP
  WHERE DEPT_NO = 0030
  AND 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_SAL
  FROM EMP WHERE ENAME LIKE 'SMITH%';
  類似的,DECODE函數也可以運用於GROUP BY 和ORDER BY子句中.
  9. 整合簡單,無關聯的資料庫訪問
  如果你有幾個簡單的資料庫查詢語句,你可以把它們整合到一個查詢中(即使它們之間沒有關係)
  例如:
  SELECT NAME
  FROM EMP
  WHERE EMP_NO = 1234;
  SELECT NAME
  FROM DPT
  WHERE DPT_NO = 10 ;
  SELECT NAME
  FROM CAT
  WHERE CAT_TYPE = 'RD';
  上面的3個查詢可以被合併成一個:
  SELECT E.NAME , D.NAME , C.NAME
  FROM CAT C , DPT D , EMP E,DUAL X
  WHERE 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(+) = 1234
  AND D.DEPT_NO(+) = 10
  AND C.CAT_TYPE(+) = 'RD';
  (譯者按: 雖然採取這種方法,效率得到提高,但是程式的可讀性大大降低,所以讀者 還是要權衡之間的利弊)
  10. 刪除重復記錄
  最高效的刪除重復記錄方法 ( 因爲使用了ROWID)
  DELETE FROM EMP E
  WHERE E.ROWID > (SELECT MIN(X.ROWID)
  FROM EMP X
  WHERE X.EMP_NO = E.EMP_NO);
  11. 用TRUNCATE替代DELETE
  當刪除表中的記錄時,在通常情況下, 回滾段(rollback segments ) 用來存放可以被恢復的資訊.
  如果你沒有COMMIT事務,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 LOCATION
  GROUP BY REGION
  HAVING REGION REGION != 'SYDNEY'
  AND REGION != 'PERTH'
  高效
  SELECT REGION,AVG(LOG_SIZE)
  FROM LOCATION
  WHERE REGION REGION != 'SYDNEY'
  AND REGION != 'PERTH'
  GROUP BY REGION
  (譯者按: HAVING 中的條件一般用於對一些集合函數的比較,如COUNT() 等等.
  除此而外,一般的條件應該寫在WHERE子句中)
  15. 減少對表的查詢
  在含有子查詢的SQL語句中,要特別注意減少對表的查詢.
  例如:
  低效
  SELECT TAB_NAME
  FROM TABLES
  WHERE TAB_NAME = ( SELECT TAB_NAME
  FROM TAB_COLUMNS
  WHERE VERSION = 604)
  ANDDB_VER= ( SELECT DB_VER
  FROM TAB_COLUMNS
  WHERE VERSION = 604)
  高效
  SELECT TAB_NAME
  FROM TABLES
  WHERE (TAB_NAME,DB_VER)
  = ( SELECT TAB_NAME,DB_VER)
  FROM TAB_COLUMNS
  WHERE VERSION = 604)
  Update 多個Column 例子:
  低效:
  UPDATE EMP
  SET EMP_CAT = (SELECT MAX(CATEGORY) FROM EMP_CATEGORIES),
  SAL_RANGE = (SELECT MAX(SAL_RANGE) FROM EMP_CATEGORIES)
  WHERE EMP_DEPT = 0020;
  高效:
  UPDATE EMP
  SET (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 H
  WHERE H.EMPNO = E.EMPNO
  AND H.HIST_TYPE = T.HIST_TYPE
  GROUP BY H.EMPNO,E.ENAME,H.HIST_TYPE,T.TYPE_DESC;
  通過調用下面的函數可以提高效率.
  FUNCTION LOOKUP_HIST_TYPE(TYP IN NUMBER) RETURN VARCHAR2
  AS
  TDESC VARCHAR2(30);
  CURSOR C1 IS
  SELECT TYPE_DESC
  FROM HISTORY_TYPE
  WHERE HIST_TYPE = TYP;
  BEGIN
  OPEN C1;
  FETCH C1 INTO TDESC;
  CLOSE C1;
  RETURN (NVL(TDESC,' '));
  END;
  FUNCTION LOOKUP_EMP(EMP IN NUMBER) RETURN VARCHAR2
  AS
  ENAME VARCHAR2(30);
  CURSOR C1 IS
  SELECT ENAME
  FROM EMP
  WHERE EMPNO=EMP;
  BEGIN
  OPEN 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 H
  GROUP BY H.EMPNO , H.HIST_TYPE;
  (譯者按: 經常在論壇中看到如 '能不能用一個SQL寫出….' 的貼子, 殊不知複雜的SQL往往犧牲了執行效率.
  能夠掌握上面的運用函數解決問題的方法在實際工作中是非常有意義的)
  17. 使用表的別名(Alias)
  當在SQL語句中連接多個表時,
  請使用表的別名並把別名字首於每個Column上.這樣一來,就可以減少解析的時間並減少那些由Column歧義引起的語法錯誤.
  (譯者注:
  Column歧義指的是由於SQL中不同的表具有相同的Column名,當SQL語句中出現這個Column時,SQL解析器無法判斷這個Column的歸屬)
  18. 用EXISTS替代IN
  在許多基於基礎表的查詢中,爲了滿足一個條件,往往需要對另一個表進行聯接.在這種情況下, 使用EXISTS(或NOT
  EXISTS)通常將提高查詢的效率.
  低效:
  SELECT *
  FROM EMP (基礎表)
  WHERE EMPNO > 0
  AND DEPTNO IN (SELECT DEPTNO
  FROM DEPT
  WHERE LOC = 'MELB')
  高效:
  SELECT *
  FROM EMP (基礎表)
  WHERE EMPNO > 0
  AND EXISTS (SELECT 'X'
  FROM DEPT
  WHERE DEPT.DEPTNO = EMP.DEPTNO
  AND LOC = 'MELB')
  (譯者按: 相對來說,用NOT EXISTS替換NOT IN 將更顯著地提高效率,下一節中將指出)
  19. 用NOT EXISTS替代NOT IN
  在子查詢中,NOT IN子句將執行一個內部的排序和合併. 無論在哪種情況下,NOT IN都是最低效的
  (因爲它對子查詢中的表執行了一個全表遍曆). 爲了避免使用NOT IN ,我們可以把它改寫成外連接(Outer Joins)或NOT
  EXISTS.
  例如:
  SELECT …
  FROM EMP
  WHERE DEPT_NO NOT IN (SELECT DEPT_NO
  FROM DEPT
  WHERE DEPT_CAT='A');
  爲了提高效率.改寫爲:
  (方法一: 高效)
  SELECT ….
  FROM EMP A,DEPT B
  WHERE A.DEPT_NO = B.DEPT(+)
  AND B.DEPT_NO IS NULL
  AND B.DEPT_CAT(+) = 'A'
  (方法二: 最高效)
  SELECT ….
  FROM EMP E
  WHERE NOT EXISTS (SELECT 'X'
  FROM DEPT D
  WHERE D.DEPT_NO = E.DEPT_NO
  AND DEPT_CAT = 'A');
  20. 用表連接替換EXISTS
  通常來說 , 採用表連接的方式比EXISTS更有效率
  SELECT ENAME
  FROM EMP E
  WHERE EXISTS (SELECT 'X'
  FROM DEPT
  WHERE DEPT_NO = E.DEPT_NO
  AND DEPT_CAT = 'A');
  (更高效)
  SELECT ENAME
  FROM DEPT D,EMP E
  WHERE E.DEPT_NO = D.DEPT_NO
  AND DEPT_CAT = 'A' ;
  (譯者按: 在RBO的情況下,前者的執行路徑包括FILTER,後者使用NESTED LOOP)

2009/05/20

MS SQL Server V.S. MS Access

MSSQLServer V.S. MSAccess


1、查詢Access中數據的方法:
select * from OpenRowSet('microsoft.jet.oledb.4.0',';database=c:\db2.mdb','select * from serv_user')

select * from OpenDataSource('Microsoft.Jet.OLEDB.4.0','Data Source="c:\DB2.mdb";User ID=Admin;Password=')...serv_user

2、從SQLServer向Access寫數據:
insert into OpenRowSet('microsoft.jet.oledb.4.0',';database=c:\db2.mdb','select * from Accee表')
select * from SQLServer表
或用BCP
master..xp_cmdshell'bcp "serv-htjs.dbo.serv_user" out "c:\db3.mdb" -c -q -S"." -U"sa" -P"sa"'
上面的區別主要是:OpenRowSet需要mdb和表存在,BCP會在不存在的時候生成該mdb

3、從Access向SQLServer寫數據:有了上面的基礎,這個就很簡單了
insert into SQLServer表 select * from
OpenRowSet('microsoft.jet.oledb.4.0',';database=c:\db2.mdb','select * from Accee表')
或用BCP
master..xp_cmdshell'bcp "serv-htjs.dbo.serv_user" in "c:\db3.mdb" -c -q -S"." -U"sa" -P"sa"'

4、刪除Access數據:
delete from OpenRowSet('microsoft.jet.oledb.4.0',';database=c:\db2.mdb','select * from serv_user')
where lock=0

5、修改Access數據:
update OpenRowSet('microsoft.jet.oledb.4.0',';database=c:\db2.mdb','select * from serv_user')
set lock=1

2009/05/14

常用T-SQL数据库函数整理

摘自:網路

1. 聚合函数
(1) AVG
函数功能 返回组中值的平均值。空值将被忽略
语法 AVG ( [ ALL | DISTINCT ] expression )
(2) MAX
函数功能 返回表达式的最大值
语法 MAX ( [ ALL | DISTINCT ] expression )
(3) MIN
函数功能 返回表达式的最小值
语法 MIN ( [ ALL | DISTINCT ] expression )
(4) SUM
函数功能 返回表达式中所有值的和,或只返回 DISTINCT 值。SUM 只能用于数字列。空值将被忽略
语法 SUM ( [ ALL | DISTINCT ] expression )
(5) COUNT
函数功能 返回组中项目的数量
语法 COUNT ( { [ ALL | DISTINCT ] expression ] | * } )



2. 时间和日期函数
(1) DATEADD
函数功能 在向指定日期加上一段时间的基础上,返回新的datetime值
语法 DATEADD ( datepart , number, date )
样例 SELECT DATEADD(day, 21, pubdate) AS timeframe FROM titles
(2) DATEPART
函数功能 返回代表指定日期的指定日期部分的整数
语法 DATEPART ( datepart , date )
样例 SELECT DATEPART(month, GETDATE()) AS 'Month Number'
(3) DAY
函数功能 返回代表指定日期的天的日期部分的整数
语法 DAY ( date )
(4) GETDATE
函数功能 按 datetime 值的 Microsoft? SQL Server? 标准内部格式返回当前系统日期和时间
语法 GETDATE ( )
(5) GETUTCDATE
函数功能 返回表示当前 UTC 时间(世界时间坐标或格林尼治标准时间)的 datetime 值。当前的 UTC 时间得自当前的本地时间和运行 SQL Server 的计算机操作系统中的时区设置
语法 GETUTCDATE()
(6) MONTH
函数功能 返回代表指定日期月份的整数
语法 MONTH ( date )
样例 SELECT "Month Number" = MONTH('03/12/1998')
(7) YEAR
函数功能 返回表示指定日期中的年份的整数
语法 YEAR ( date )



3. 数学函数
(1) ABS
函数功能 返回给定数字表达式的绝对值
语法 ABS ( numeric_expression )
(2) RAND
函数功能 返回 0 到1 之间的随机float 值
语法 RAND ( [ seed ] ) :seed是给出种子值或起始值的整型表达式(tinyint、smallint 或 int)
(3) ROUND
函数功能 返回数字表达式并四舍五入为指定的长度或精度
语法 ROUND ( numeric_expression , length [ , function ] )
(4) FLOOR
函数功能 返回小于或等于所给数返回小于或等于所给数字表达式的最大整数字表达式的最大整数
语法 FLOOR ( numeric_expression )
(5) SIGN
函数功能 返回给定表达式的正 (+1)、零 (0) 或负 (-1) 号
语法 SIGN ( numeric_expression )
(6) SQUARE
函数功能 返回给定表达式的平方
语法 SQUARE ( float_expression )
样例



3. 系统函数
(1) CAST 和 CONVERT
函数功能 将某种数据类型的表达式显式转换为另一种数据类型。CAST 和 CONVERT 提供相似的功能
语法 CAST ( expression AS data_type )
CONVERT (data_type[(length)], expression [, style])
样例 DECLARE @myval decimal (5, 2)
SET @myval = 193.57
SELECT CAST(CAST(@myval AS varbinary(20)) AS decimal(10,5))
-- Or, using CONVERT
SELECT CONVERT(decimal(10,5), CONVERT(varbinary(20), @myval))
(2) COALESCE
函数功能 返回其参数中第一个非空表达式
语法 COALESCE ( expression [ ,...n ] )
样例 SELECT CAST(COALESCE(hourly_wage * 40 * 52, salary, commission * num_sales) AS money) AS 'Total Salary' FROM wages
(3) DATALENGTH
函数功能 返回任何表达式所占用的字节数
语法 DATALENGTH ( expression )
(4) @@ERROR
函数功能 返回最后执行的 Transact-SQL 语句的错误代码
语法 @@ERROR
样例 IF @@ERROR = 547
print "A check constraint violation occurred"
(5) ISDATE
函数功能 确定输入表达式是否为有效的日期
语法 ISDATE ( expression )
(6) ISNULL
函数功能 使用指定的替换值替换 NULL
语法 ISNULL ( check_expression , replacement_value )
(7) ISNUMERIC
函数功能 确定表达式是否为一个有效的数字类型
语法 ISNUMERIC ( expression )
(8) NULLIF
函数功能 如果两个指定的表达式相等,则返回空值
语法 NULLIF ( expression , expression )
(9) @@ROWCOUNT
函数功能 返回受上一语句影响的行数
语法 @@ROWCOUNT



4. 游标函数
(1) @@CURSOR_ROWS
函数功能 返回连接上最后打开的游标中当前存在的合格行的数量。为提高性能,Microsoft? SQL Server? 可以异步填充大键集和静态游标。可调用 @@CURSOR_ROWS,以确定当它被调用时,符合游标的行的数目被进行了检索
语法 @@CURSOR_ROWS
样例 SELECT @@CURSOR_ROWS
DECLARE authors_cursor CURSOR FOR
SELECT au_lname FROM authors
OPEN authors_cursor
FETCH NEXT FROM authors_cursor
SELECT @@CURSOR_ROWS
CLOSE authors_cursor
DEALLOCATE authors_cursor
(2) @@FETCH_STATUS
函数功能 返回被 FETCH 语句执行的最后游标的状态,而不是任何当前被连接打开的游标的状态
语法 @@FETCH_STATUS
样例 DECLARE Employee_Cursor CURSOR FOR
SELECT LastName, FirstName FROM Northwind.dbo.Employees
OPEN Employee_Cursor
FETCH NEXT FROM Employee_Cursor
WHILE @@FETCH_STATUS = 0
BEGIN
FETCH NEXT FROM Employee_Cursor
END
CLOSE Employee_Cursor
DEALLOCATE Employee_Cursor



5. 元数据函数
(1) COL_LENGTH
函数功能 返回列的定义长度(以字节为单位)
语法 COL_LENGTH ( 'table' , 'column' )
(2) COL_NAME
函数功能 返回数据库列的名称,该列具有相应的表标识号和列标识号
语法 COL_NAME ( table_id , column_id )
(3) INDEX_COL
函数功能 返回索引列名称
语法 INDEX_COL ( 'table' , index_id , key_id )
(3) DB_NAME
函数功能 返回数据库名
语法 DB_NAME ( database_id )
(3) OBJECT_ID
函数功能 返回数据库对象标识号
语法 OBJECT_ID ( 'object' )
样例 SELECT OBJECT_ID('pubs..authors')
(4) OBJECT_NAME
函数功能 返回数据库对象名
语法 OBJECT_NAME ( object_id )
(5) @@PROCID
函数功能 返回当前过程的存储过程标识符 (ID)
语法 @@PROCID
(6) TYPEPROPERTY
函数功能 返回有关数据类型的信息
语法 TYPEPROPERTY ( type , property )
样例 SELECT TYPEPROPERTY( 'tinyint', 'PRECISION')



6. 字符串函数
(1) ASCII
函数功能 返回字符表达式最左端字符的 ASCII 代码值
语法 ASCII ( character_expression )
(2) CHAR
函数功能 将 int ASCII 代码转换为字符的字符串函数
语法 CHAR ( integer_expression )
(3) CHARINDEX
函数功能 返回字符串中指定表达式的起始位置
语法 CHARINDEX ( expression1 , expression2 [ , start_location ] )
参数 expression1:一个表达式,其中包含要寻找的字符的次序。expression1 是一个短字符数据类型分类的表达式。
expression2:一个表达式,通常是一个用于搜索指定序列的列。expression2 属于字符串数据类型分类。
(4) DIFFERENCE
函数功能 以整数返回两个字符表达式的 SOUNDEX 值之差
语法 DIFFERENCE ( character_expression , character_expression )
(5) LEFT
函数功能 返回从字符串左边开始指定个数的字符
语法 LEFT ( character_expression , integer_expression )
(6) LEN
函数功能 返回给定字符串表达式的字符(而不是字节)个数,其中不包含尾随空格
语法 LEN ( string_expression )
(7) LOWER
函数功能 将大写字符数据转换为小写字符数据后返回字符表达式
语法 LOWER ( character_expression )
(8) LTRIM
函数功能 删除起始空格后返回字符表达式
语法 LTRIM ( character_expression )
(9) NCHAR
函数功能 根据 Unicode 标准所进行的定义,用给定整数代码返回 Unicode 字符
语法 NCHAR ( integer_expression )
样例
(10) PATINDEX
函数功能 返回指定表达式中某模式第一次出现的起始位置;如果在全部有效的文本和字符数据类型中没有找到该模式,则返回零
语法 PATINDEX ( '%pattern%' , expression )
(11) PEPLACE
函数功能 用第三个表达式替换第一个字符串表达式中出现的所有第二个给定字符串表达式
语法 REPLACE ( 'string_expression1' , 'string_expression2' , 'string_expression3' )
(12) REVERSE
函数功能 返回字符表达式的反转
语法 REVERSE ( character_expression )
(13) RIGHT
函数功能 返回字符串中从右边开始指定个数的 integer_expression 字符
语法 RIGHT ( character_expression , integer_expression )
(14) RTRIM
函数功能 截断所有尾随空格后返回一个字符串
语法 RTRIM ( character_expression )
(15) SOUNDEX
函数功能 返回由四个字符组成的代码 (SOUNDEX) 以评估两个字符串的相似性
语法 SOUNDEX ( character_expression )
(16) SPACE
函数功能 返回由重复的空格组成的字符串
语法 SPACE ( integer_expression )
(17) STR
函数功能 由数字数据转换来的字符数据
语法 STR ( float_expression [ , length [ , decimal ] ] )
参数 float_expression: 是带小数点的近似数字 (float) 数据类型的表达式。不要在 STR 函数中将函数或子查询用作 float_expression。
length: 是总长度,包括小数点、符号、数字或空格。默认值为 10。
decimal: 是小数点右边的位数。
(18) STUFF
函数功能 删除指定长度的字符并在指定的起始点插入另一组字符
语法 STUFF ( character_expression , start , length , character_expression )
(19) SUBSTRING
函数功能 返回字符、binary、text 或 image 表达式的一部分。有关可与该函数一起使用的有效 Microsoft? SQL Server? 数据类型的更多信息
语法 SUBSTRING ( expression , start , length )
(20) UNICODE
函数功能 按照 Unicode 标准的定义,返回输入表达式的第一个字符的整数值
语法 UNICODE ( 'ncharacter_expression' )
(21) UPPER
函数功能 返回将小写字符数据转换为大写的字符表达式
语法 UPPER ( character_expression )

2009/05/13

LogExplore操作手册

摘自:網路

  介绍

  Log Explorer主要用于对MSSQLServer的事物分析和数据恢复。你可以浏览日志、导出数据、恢复被修改或者删除的数据(包括执行过 update,delete,drop和truncate语句的表格)。一旦由于系统故障或者人为因素导致数据丢失,它能够提供在线快速的数据恢复,最大程度上保证恢复期间的其他事物不间断执行。

  他可以支持SQLServer7.0和SQLServer2000,提取标准数据库的日志文件或者备份文件中的信息。

  其中提供两个强大的工具:日志分析浏览,对象恢复。具体功能如下:

  l     日志文件浏览

  l     数据库变更审查

  l     计划和授权变更审查

  l     将日志记录导出到文件或者数据库表

  l     实时监控数据库事物

  l     计算并统计负荷

  l     通过有选择性的取消或者重做事物来恢复数据

  l     恢复被截断或者删除表中的数据

  l     运行SQL脚本

  产品

  LogExplore包含两部分

  l     客户端软件

  l     服务器代理

  服务器端代理是保存在SQLServer主机中的一个只读存储过程,他的作用是接受客户端请求,读取在线事物日志块并通过网络传给客户端软件,由客户端软件来读取这些原始的数据块来完成Log Explore所提供的所有功能。

  他依赖来的网络协议包括:

  l     Named Pipe:局域网中适用

  l     Tcp/Ip:广域网中适用

  数据库相关介绍

  事物日志(Transaction Log)

  SQLServer的每个数据库都包含事物日志,它以文件的形式存储,可以记录数据库的任何变化。发生故障时SQLServer就是通过它来保证数据的完整性。

  操作(Operation)

  操作是数据库中定义的"原子行为",每个操作都在日志文件中保存为一条记录。它可以是用户直接输入的SQL语句,比如标准的insert命令,日志文件中便会记录一条操作代码来标志这个insert操作。

  事物(Transaction)

  事物是一系列操作组成的序列。他可以理解为直观的不可分割的一笔业务,可以执行成功或者失败。典型的事物比如由应用程序发出的具有开启-提交功能的一组SQL语句。不同的事物靠事物Id号(transaction ID)来区分,具有相同ID的事物记录的日志也相同。

  在线事物日志(Online Transaction Log)

  在线事物日志是指当前活动数据库所用的日志。可以通过如下命令来确定其对应文件

  Select * from SYSFILES

  他的文件后缀名一般是.LDF

  离线事物日志(Offline Transaction Log)

  离线事物日志是指非活动数据库所用的日志。当其数据库处于关闭(ShutDown)才状态下可以进行复制备份操作。他的结果同在线事物日志完全相同。

  备份文件

  备份文件是保存食物日志备份的文件,通常管理员通过运行SQL语句或者企业管理器来生成该文件。备份文件的内部结构和事物日志不同,他采用称为MTF的格式来保存数据。一个备份文件可以包含一个日志的多组备份,甚至包括多个数据库的混合备份.

  设置为自动收缩

  企业管理器--服务器--右键数据库--属性--选项--选择"自动收缩"

  强烈要求该项不要选中.否则SQLServer将已循环的方式来覆盖先前的日志记录,将会导致LogExplore无法恢复错误.

  数据恢复介绍

  LogExplore允许你恢复应为误操作或者程序错误而导致的数据丢失或者更改.比如执行updateDelete语句时丢失了where子句,或者错误使用了Dts功能.

  LogExplore不支持直接修改数据库.他可以生成事物的逆操作脚本.

  如果log是delete table where ...的话,生成的文件代码就是insert table ....

  你可以通过SQL查询分析器,或者LogExplore的Run SQL Script功能来执行生成脚本.

  关于Undo

  Undo功能可以逆操作一组指定的用户事物。包括insert,delete和update,其局限性如下:

  l     事物类别:LogExplore只能undo用户事物。用户事物是指在用户表上定义的事物,不支持系统表的更新恢复。同时,他也不支持计划变更的回滚。

  l     Blob类型:包括text,ntext,image类型。LogExplore只支持这些类型的insert和delete恢复,不支持update语句恢复。

  关于redo

  Redo功能可以再次运行一组指定事物。它可以在以下情况中用到:

  丢失数据库而且没有任何备份文件。

  l     如果原始日志文件没有丢失可以通过Redo来实现恢复。

  l     通过完整备份文件来把数据库恢复到某指定时间点,再通过redo功能完整恢复。它可以重放Create Table和Create Index命令,来重新生成被删掉的表,同时也受blob字段的限制。

  拯救Dropped/Truncate命令导致的数据丢失

  执行Drop Table和Truncate Table命令虽然会被SQLServer记录到日志文件中,但是并不记录被删除的数据。你可以使用LogExplore提供的功能来恢复这些数据。 LogExplore提供两种机制来恢复被Drop或者Truncate的数据。

  1、如果你有备份文件可以直接通过备份文件恢复。

  2、通过LogExplore提供的方法来恢复。

  当执行如上命令时,SQLServer会将保存数据的页面放入空闲页面列表中。如果此页没有被再次使用则将一直保存原始数据。恢复时,LogExplore将从空闲页面列表中搜寻没有被再次使用的页面,然后生成一个SQL脚本来从这些页面重组原始数据。LogExplore可以确定被删掉的原始数据行,并在完成时显示原始行数和实际恢复的行数,由此可以断定是否全部恢复。

  SQL逆操作

  1、Insert--Delete

  2、Delete--Insert

  3、Update

  注意:如果你选中了'Do not restore column values that have been changed by subsequent modifications'项,只对事物1逆转将不会产生任何结果。

  自增序列(IDENTITY Property)

  如果被删除数据与有IDENTITY Property属性,恢复时LogExlpore可以通过SET IDENTITY_INSERT ON 命令来对插入的数据设置Identity属性,并保留原数据不变,也可以对该列付与新值。

  数据导出:

  浏览日志时可将数据导出为xml,html,或者其他有分隔符的文件.也可以指定到一个SQL的表中.

  操作指南

  Attaching to a Log:在所有操作之前必须添加日志文件,

  l     可以用普通的SQL登录方式添加在线日志(Online Log),

  l     直接选择LDF文件来添加离线日志(OffLine Log)

  l     添加备份文件

  登录之后界

LogExplore的一个详细操作手册

  功能介绍:

  1、 Log Summary

  日志文件的概要信息。

  2、 Load Analysis

  列出指定时间范围内的一些事物,用户和表载入的概要信息。

  3、 Filter Log Record

  日志过滤设置。支持过滤条件包括:时间、操作类型、表、用户、SPID、搜索深度、Dropped表项以及登录设置和应用程序设置

  4、Browse

  日志浏览,核心模块。

LogExplore的一个详细操作手册

  1、 View Log功能:

  列表如图,可以用TransID来区分事物并用不同颜色标识。工具栏的按钮是一些基本查询操作。鼠标右键弹出菜单中有Undo Transaction和UndoOperation可以恢复黑色箭头选中的事物或者操作项。

  Real-Time Monitor:

  实时监控事物日志,通过轮询来实现。可以暂停或者停止监控,可以更改轮询周期。

  相关DML语言和DDL语言可以在Row Revision History、Row Transaction History以及View DDL Commands来查询。

  2、 Export Log Report

  包括Export To SQL和Export To File,根据向导即可完成。

  3、 其余菜单:Undo,Redo,Salvage Dropped/Truncated data,Restore 以及Run SQL Script前面已经叙述过,可以根据其向导完成。

  log explorer使用的几个问题

  1)对数据库做了完全 差异 和日志备份

  备份时选用了删除事务日志中不活动的条目

  再用Log explorer打试图看日志时

  提示No log recorders found that match the filter,would you like to view unfiltered data

  选择yes 就看不到刚才的记录了

  如果不选用了删除事务日志中不活动的条目

  再用Log explorer打试图看日志时,就能看到原来的日志

  2)修改了其中一个表中的部分数据,此时用Log explorer看日志,可以作日志恢复

  3)然后恢复备份,(注意:恢复是断开log explorer与数据库的连接,或连接到其他数据上,

  否则会出现数据库正在使用无法恢复)

  恢复完后,再打开log explorer 提示No log recorders found that match the filter,would you like to view unfiltered data

  选择yes 就看不到刚才在2中修改的日志记录,所以无法做恢复.

  3)

  不要用SQL的备份功能备份,搞不好你的日志就破坏了.

  正确的备份方法是:

  停止SQL服务,复制数据文件及日志文件进行文件备份.

  然后启动SQL服务,用log explorer恢复数据

  LogExplore

  下载地址: http://js.fixdown.com/soft/8324.asp?free=gdcnc-down1

  介绍

  Log Explorer主要用于对MSSQLServer的事物分析和数据恢复。你可以浏览日志、导出数据、恢复被修改或者删除的数据(包括执行过 update,delete,drop和truncate语句的表格)。一旦由于系统故障或者人为因素导致数据丢失,它能够提供在线快速的数据恢复,最大程度上保证恢复期间的其他事物不间断执行。

  他可以支持SQLServer7.0和SQLServer2000,提取标准数据库的日志文件或者备份文件中的信息。

  其中提供两个强大的工具:日志分析浏览,对象恢复。具体功能如下:

  l     日志文件浏览

  l     数据库变更审查

  l     计划和授权变更审查

  l     将日志记录导出到文件或者数据库表

  l     实时监控数据库事物

  l     计算并统计负荷

  l     通过有选择性的取消或者重做事物来恢复数据

  l     恢复被截断或者删除表中的数据

  l     运行SQL脚本

  产品

  LogExplore包含两部分

  l     客户端软件

  l     服务器代理

  服务器端代理是保存在SQLServer主机中的一个只读存储过程,他的作用是接受客户端请求,读取在线事物日志块并通过网络传给客户端软件,由客户端软件来读取这些原始的数据块来完成Log Explore所提供的所有功能。

  他依赖来的网络协议包括:

  l     Named Pipe:局域网中适用

  l     Tcp/Ip:广域网中适用

  数据库相关介绍

  事物日志(Transaction Log)

  SQLServer的每个数据库都包含事物日志,它以文件的形式存储,可以记录数据库的任何变化。发生故障时SQLServer就是通过它来保证数据的完整性。

  操作(Operation)

  操作是数据库中定义的"原子行为",每个操作都在日志文件中保存为一条记录。它可以是用户直接输入的SQL语句,比如标准的insert命令,日志文件中便会记录一条操作代码来标志这个insert操作。

  事物(Transaction)

  事物是一系列操作组成的序列。他可以理解为直观的不可分割的一笔业务,可以执行成功或者失败。典型的事物比如由应用程序发出的具有开启-提交功能的一组SQL语句。不同的事物靠事物Id号(transaction ID)来区分,具有相同ID的事物记录的日志也相同。

  在线事物日志(Online Transaction Log)

  在线事物日志是指当前活动数据库所用的日志。可以通过如下命令来确定其对应文件

  Select * from SYSFILES

  他的文件后缀名一般是.LDF

  离线事物日志(Offline Transaction Log)

  离线事物日志是指非活动数据库所用的日志。当其数据库处于关闭(ShutDown)才状态下可以进行复制备份操作。他的结果同在线事物日志完全相同。

  备份文件

  备份文件是保存食物日志备份的文件,通常管理员通过运行SQL语句或者企业管理器来生成该文件。备份文件的内部结构和事物日志不同,他采用称为MTF的格式来保存数据。一个备份文件可以包含一个日志的多组备份,甚至包括多个数据库的混合备份.

  设置为自动收缩

  企业管理器--服务器--右键数据库--属性--选项--选择"自动收缩"

  强烈要求该项不要选中.否则SQLServer将已循环的方式来覆盖先前的日志记录,将会导致LogExplore无法恢复错误.

  数据恢复介绍

  LogExplore允许你恢复应为误操作或者程序错误而导致的数据丢失或者更改.比如执行updateDelete语句时丢失了where子句,或者错误使用了Dts功能.

  LogExplore不支持直接修改数据库.他可以生成事物的逆操作脚本.

  如果log是delete table where ...的话,生成的文件代码就是insert table ....

  你可以通过SQL查询分析器,或者LogExplore的Run SQL Script功能来执行生成脚本.

  关于Undo

  Undo功能可以逆操作一组指定的用户事物。包括insert,delete和update,其局限性如下:

  l     事物类别:LogExplore只能undo用户事物。用户事物是指在用户表上定义的事物,不支持系统表的更新恢复。同时,他也不支持计划变更的回滚。

  l     Blob类型:包括text,ntext,image类型。LogExplore只支持这些类型的insert和delete恢复,不支持update语句恢复。

  关于redo

  Redo功能可以再次运行一组指定事物。它可以在以下情况中用到:

  丢失数据库而且没有任何备份文件。

  l     如果原始日志文件没有丢失可以通过Redo来实现恢复。

  l     通过完整备份文件来把数据库恢复到某指定时间点,再通过redo功能完整恢复。它可以重放Create Table和Create Index命令,来重新生成被删掉的表,同时也受blob字段的限制。

  拯救Dropped/Truncate命令导致的数据丢失

  执行Drop Table和Truncate Table命令虽然会被SQLServer记录到日志文件中,但是并不记录被删除的数据。你可以使用LogExplore提供的功能来恢复这些数据。 LogExplore提供两种机制来恢复被Drop或者Truncate的数据。

  1、如果你有备份文件可以直接通过备份文件恢复。

  2、通过LogExplore提供的方法来恢复。

  当执行如上命令时,SQLServer会将保存数据的页面放入空闲页面列表中。如果此页没有被再次使用则将一直保存原始数据。恢复时,LogExplore将从空闲页面列表中搜寻没有被再次使用的页面,然后生成一个SQL脚本来从这些页面重组原始数据。LogExplore可以确定被删掉的原始数据行,并在完成时显示原始行数和实际恢复的行数,由此可以断定是否全部恢复。

  SQL逆操作

  1、Insert--Delete

  2、Delete--Insert

  3、Update

  注意:如果你选中了'Do not restore column values that have been changed by subsequent modifications'项,只对事物1逆转将不会产生任何结果。

  自增序列(IDENTITY Property)

  如果被删除数据与有IDENTITY Property属性,恢复时LogExlpore可以通过SET IDENTITY_INSERT ON 命令来对插入的数据设置Identity属性,并保留原数据不变,也可以对该列付与新值。

  数据导出:

  浏览日志时可将数据导出为xml,html,或者其他有分隔符的文件.也可以指定到一个SQL的表中.

  操作指南

  Attaching to a Log:在所有操作之前必须添加日志文件,

  l     可以用普通的SQL登录方式添加在线日志(Online Log),

  l     直接选择LDF文件来添加离线日志(OffLine Log)

  l     添加备份文件

  登录之后界面

Column1 Column2 
A B

  事物1

Column1 Column2 
X B

  事物2

Column1 Column2 
Z T

  你可以只对事物1做逆操作

Column1 Column2 
A T

Column1 Column2 
A B

  事物1

Column1 Column2 
X B

  事物2

Column1 Column2 
Z T

  你可以只对事物1做逆操作

Column1 Column2 
A T

来源:csdn 作者:贾涛 责编:豆豆技术应用