`
Callan
  • 浏览: 737750 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Oracle语句优化53个规则详解(2)

阅读更多
31.       强制索引失效

    如果两个或以上索引具有相同的等级,你可以强制命令ORACLE优化器使用其中的一个(通过它,检索出的记录数量少) .

    举例:

    SELECT ENAME
 FROM EMP
 WHERE EMPNO = 7935
 AND DEPTNO + 0 = 10    /*DEPTNO上的索引将失效*/
 AND EMP_TYPE || ‘’ = ‘A’  /*EMP_TYPE上的索引将失效*/

    这是一种相当直接的提高查询效率的办法。 但是你必须谨慎考虑这种策略,一般来说,只有在你希望单独优化几个SQL时才能采用它。

    这里有一个例子关于何时采用这种策略,

    假设在EMP表的EMP_TYPE列上有一个非唯一性的索引而EMP_CLASS上没有索引。

    SELECT ENAME
 FROM EMP
 WHERE EMP_TYPE = ‘A’
 AND EMP_CLASS = ‘X’;

    优化器会注意到EMP_TYPE上的索引并使用它。 这是目前唯一的选择。 如果,一段时间以后, 另一个非唯一性建立在EMP_CLASS上,优化器必须对两个索引进行选择,在通常情况下,优化器将使用两个索引并在他们的结果集合上执行排序及合并。 然而,如果其中一个索引(EMP_TYPE)接近于唯一性而另一个索引(EMP_CLASS)上有几千个重复的值。 排序及合并就会成为一种不必要的负担。 在这种情况下,你希望使优化器屏蔽掉EMP_CLASS索引。

    用下面的方案就可以解决问题。

    SELECT ENAME
 FROM EMP
 WHERE EMP_TYPE = ‘A’
 AND EMP_CLASS||‘’ = ‘X’;


32.       避免在索引列上使用计算。

    WHERE子句中,如果索引列是函数的一部分。优化器将不使用索引而使用全表扫描。

    举例:

    低效:

 SELECT …
    FROM DEPT
WHERE SAL * 12 > 25000;

    高效:

 SELECT …
    FROM DEPT
 WHERE SAL > 25000/12;

    译者按:这是一个非常实用的规则,请务必牢记

    33.       自动选择索引

 如果表中有两个以上(包括两个)索引,其中有一个唯一性索引,而其他是非唯一性。

    在这种情况下,ORACLE将使用唯一性索引而完全忽略非唯一性索引。

    举例:

 SELECT ENAME
 FROM EMP
 WHERE EMPNO = 2326
 AND DEPTNO = 20 ;

    这里,只有EMPNO上的索引是唯一性的,所以EMPNO索引将用来检索记录。

    TABLE ACCESS BY ROWID ON EMP
  INDEX UNIQUE SCAN ON EMP_NO_IDX

    34.       避免在索引列上使用NOT

 通常,我们要避免在索引列上使用NOT, NOT会产生在和在索引列上使用函数相同的影响。 当ORACLE“遇到”NOT,他就会停止使用索引转而执行全表扫描。

    举例:

    低效: (这里,不使用索引)

    SELECT …
    FROM DEPT
 WHERE DEPT_CODE NOT = 0;

    高效: (这里,使用了索引)

    SELECT …
    FROM DEPT
 WHERE DEPT_CODE > 0;

    需要注意的是,在某些时候, ORACLE优化器会自动将NOT转化成相对应的关系操作符。

    NOT > to <=
 NOT >= to <
 NOT < to >=
 NOT <= to >

    译者按:在这个例子中,作者犯了一些错误。 例子中的低效率SQL是不能被执行的。

    我做了一些测试:

    SQL> select * from emp where NOT empno > 1;
 no rows selected
 Execution Plan

 ----------------------------------------------------------

    0      SELECT STATEMENT Optimizer=CHOOSE
 1    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 selected
 Execution Plan

 ----------------------------------------------------------

    0      SELECT STATEMENT Optimizer=CHOOSE
 1    0   TABLE ACCESS (BY INDEX ROWID) OF 'EMP'
 2    1     INDEX (RANGE SCAN) OF 'EMPNO' (UNIQUE)

    两者的效率完全一样,也许这符合作者关于“ 在某些时候, ORACLE优化器会自动将NOT转化成相对应的关系操作符” 的观点。

    35.       用>=替代>

    如果DEPTNO上有一个索引,

    高效:

    SELECT *
 FROM EMP
 WHERE DEPTNO >=4

    低效:

    SELECT *
 FROM EMP
 WHERE 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 , 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, 那就需要返回记录最少的索引列写在最前面。

    注意:

    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=CHOOSE
 1    0   CONCATENATION
 2    1     TABLE ACCESS (BY INDEX ROWID) OF 'UNIONVSOR'
 3    2       INDEX (RANGE SCAN) OF 'UB' (NON-UNIQUE)
    4    1     TABLE ACCESS (BY INDEX ROWID) OF 'UNIONVSOR'
 5    4       INDEX (RANGE SCAN) OF 'UA' (NON-UNIQUE)

    Statistics

 ----------------------------------------------------------

    0 recursive calls
 0 db block gets
 144 consistent gets
 0 physical reads
 0 redo size
 63749 bytes sent via SQL*Net to client
 7751 bytes received via SQL*Net from client
 68 SQL*Net roundtrips to/from client
 0 sorts (memory)
    0 sorts (disk)
    1003 rows processed

 SQL> select * from unionvsor /*2nd test*/
 2 where b = 1 or a = 1003 ;
 1003 rows selected.
 Execution Plan

 ----------------------------------------------------------

    0      SELECT STATEMENT Optimizer=CHOOSE
 1    0   CONCATENATION
 2    1     TABLE ACCESS (BY INDEX ROWID) OF 'UNIONVSOR'
 3    2       INDEX (RANGE SCAN) OF 'UA' (NON-UNIQUE)
    4    1     TABLE ACCESS (BY INDEX ROWID) OF 'UNIONVSOR'
 5    4       INDEX (RANGE SCAN) OF 'UB' (NON-UNIQUE)

    Statistics

 ----------------------------------------------------------

    0 recursive calls
 0 db block gets
 143 consistent gets
 0 physical reads
 0 redo size
 63749 bytes sent via SQL*Net to client
 7751 bytes received via SQL*Net from client
 68 SQL*Net roundtrips to/from client 0 sorts (memory)
    0 sorts (disk)
    1003 rows processed

    SQL> select * from unionvsor /*3rd test*/
 2 where a = 1003
 3 union
 4   select * from unionvsor
 5   where b = 1;
 1003 rows selected. Execution Plan

 ----------------------------------------------------------

    0      SELECT STATEMENT Optimizer=CHOOSE
 1    0   SORT (UNIQUE)
    2    1     UNION-ALL
 3    2       TABLE ACCESS (BY INDEX ROWID) OF 'UNIONVSOR'
 4    3         INDEX (RANGE SCAN) OF 'UA' (NON-UNIQUE)
    5    2       TABLE ACCESS (BY INDEX ROWID) OF 'UNIONVSOR'
 6    5         INDEX (RANGE SCAN) OF 'UB' (NON-UNIQUE)

    Statistics

 ----------------------------------------------------------

    0 recursive calls
 0 db block gets
 10 consistent gets
 0 physical reads
 0 redo size
 63735 bytes sent via SQL*Net to client
 7751 bytes received via SQL*Net from client
 68 SQL*Net roundtrips to/from client 1 sorts (memory)
    0 sorts (disk)
    1003 rows processed

 用UNION的效果可以从consistent gets和 SQL*NET的数据交换量的减少看出

    37.       用IN来替换OR

    下面的查询可以被更有效率的语句替换:

    低效:

    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);

    译者按:这是一条简单易记的规则,但是实际的执行效果还须检验,在ORACLE8i下,两者的执行路径似乎是相同的。


38.       避免在索引列上使用IS NULL和IS 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;

 39.       总是使用索引的第一个列

 如果索引是建立在多个列上, 只有在它的第一个列(leading column)被where子句引用时,优化器才会选择使用该索引。

    译者按:这也是一条简单而重要的规则。 见以下实例。

    SQL> create table multiindexusage ( inda number , indb number , descr varchar2(10));
 Table created.
 SQL> create index multindex on multiindexusage(inda,indb);
 Index created.
 SQL> set autotrace traceonly
    SQL> select * from multiindexusage where inda = 1;
 Execution Plan

 ----------------------------------------------------------

    0      SELECT STATEMENT Optimizer=CHOOSE
 1    0   TABLE ACCESS (BY INDEX ROWID) OF 'MULTIINDEXUSAGE'
 2    1     INDEX (RANGE SCAN) OF 'MULTINDEX' (NON-UNIQUE)

    SQL> select * from multiindexusage where indb = 1;
 Execution Plan

 ----------------------------------------------------------

    0      SELECT STATEMENT Optimizer=CHOOSE
 1    0   TABLE ACCESS (FULL) OF 'MULTIINDEXUSAGE'

    很明显, 当仅引用索引的第二个列时,优化器使用了全表扫描而忽略了索引

    40.       ORACLE内部操作

 当执行查询时,ORACLE采用了内部的操作。 下表显示了几种重要的内部操作。

ORACLE Clause 内部操作
ORDER BY SORT ORDER BY
UNION UNION-ALL
MINUS MINUS
INTERSECT INTERSECT
DISTINCT,MINUS,INTERSECT,UNION SORT UNIQUE
MIN,MAX,COUNT SORT AGGREGATE
GROUP BY SORT GROUP BY
ROWNUM COUNT or COUNT STOPKEY
Queries involving Joins SORT JOIN,MERGE JOIN,NESTED LOOPS
CONNECT BY CONNECT BY


    41.       用UNION-ALL 替换UNION ( 如果有可能的话)

    当SQL语句需要UNION两个查询结果集合时,这两个结果集合会以UNION-ALL的方式被合并, 然后在输出最终结果前进行排序。

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

    举例:

 低效:

 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’

    译者按:需要注意的是,UNION ALL 将重复输出两个结果集合中相同记录。 因此各位还是要从业务需求分析使用UNION ALL的可行性。

    UNION 将对结果集合排序,这个操作会使用到SORT_AREA_SIZE这块内存。 对于这块内存的优化也是相当重要的。 下面的SQL可以用来查询排序的消耗量

    Select substr(name,1,25) "Sort Area Name",
 substr(value,1,15)   "Value"
 from v$sysstat
 where name like 'sort%'

42.       使用提示(Hints)

    对于表的访问,可以使用两种Hints.

 FULL 和 ROWID

    FULL hint 告诉ORACLE使用全表扫描的方式访问指定表。

    例如:

 SELECT /*+ FULL(EMP) */ *
 FROM EMP
 WHERE EMPNO = 7893;

    ROWID hint 告诉ORACLE使用TABLE ACCESS BY ROWID的操作访问表。

    通常, 你需要采用TABLE ACCESS BY ROWID的方式特别是当访问大表的时候, 使用这种方式, 你需要知道ROIWD的值或者使用索引。

    如果一个大表没有被设定为缓存(CACHED)表而你希望它的数据在查询结束是仍然停留在SGA中,你就可以使用CACHE hint 来告诉优化器把数据保留在SGA中。 通常CACHE hint 和 FULL hint 一起使用。

    例如:

 SELECT /*+ FULL(WORKER) CACHE(WORKER)*/ *
 FROM WORK;

    索引hint 告诉ORACLE使用基于索引的扫描方式。 你不必说明具体的索引名称

 例如:

 SELECT /*+ INDEX(LODGING) */ LODGING
 FROM LODGING
 WHERE MANAGER = ‘BILL GATES’;

    在不使用hint的情况下, 以上的查询应该也会使用索引,然而,如果该索引的重复值过多而你的优化器是CBO, 优化器就可能忽略索引。 在这种情况下, 你可以用INDEX hint强制ORACLE使用该索引。

    ORACLE hints 还包括ALL_ROWS, FIRST_ROWS, RULE,USE_NL, USE_MERGE, USE_HASH 等等。

    译者按:使用hint , 表示我们对ORACLE优化器缺省的执行路径不满意,需要手工修改。这是一个很有技巧性的工作。 我建议只针对特定的,少数的SQL进行hint的优化。对ORACLE的优化器还是要有信心(特别是CBO)

    43.       用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

    非唯一性的索引(DEPT_TYPE)

    低效: (索引不被使用)

    SELECT DEPT_CODE
 FROM DEPT
 ORDER BY DEPT_TYPE

    EXPLAIN PLAN:
  SORT ORDER BY
    TABLE ACCESS FULL

 高效: (使用索引)

    SELECT DEPT_CODE
 FROM DEPT
 WHERE DEPT_TYPE > 0

 EXPLAIN PLAN:
  TABLE ACCESS BY ROWID ON EMP
   INDEX RANGE SCAN ON DEPT_IDX

 译者按:ORDER BY 也能使用索引! 这的确是个容易被忽视的知识点。 我们来验证一下:

SQL> select * from emp order by empno;
Execution Plan

----------------------------------------------------------

    0      SELECT STATEMENT Optimizer=CHOOSE
 1    0   TABLE ACCESS (BY INDEX ROWID) OF 'EMP'
 2    1     INDEX (FULL SCAN) OF 'EMPNO' (UNIQUE)

    44.       避免改变索引列的类型。

    当比较不同数据类型的数据时, ORACLE自动对列进行简单的类型转换。

    假设 EMPNO是一个数值类型的索引列。

    SELECT …
    FROM EMP
 WHERE EMPNO = ‘123’

 实际上,经过ORACLE类型转换, 语句转化为:

 SELECT …
    FROM EMP
 WHERE EMPNO = TO_NUMBER(‘123’)

    幸运的是,类型转换没有发生在索引列上,索引的用途没有被改变。

    现在,假设EMP_TYPE是一个字符类型的索引列。

    SELECT …
    FROM EMP
WHERE EMP_TYPE = 123

 这个语句被ORACLE转换为:

 SELECT …
    FROM EMP
 WHERE TO_NUMBER(EMP_TYPE)=123

 因为内部发生的类型转换, 这个索引将不会被用到!

    译者按:为了避免ORACLE对你的SQL进行隐式的类型转换, 最好把类型转换用显式表现出来。 注意当字符和数值比较时, ORACLE会优先转换数值类型到字符类型。

45.       需要当心的WHERE子句

 某些SELECT 语句中的WHERE子句不使用索引。 这里有一些例子。

    在下面的例子里, ‘!=’ 将不使用索引。 记住, 索引只能告诉你什么存在于表中, 而不能告诉你什么不存在于表中。

    不使用索引:

 SELECT ACCOUNT_NAME
 FROM TRANSACTION
 WHERE AMOUNT !=0;

 使用索引:

 SELECT ACCOUNT_NAME
 FROM TRANSACTION
 WHERE AMOUNT >0;

 下面的例子中, ‘||’是字符连接函数。 就象其他函数那样, 停用了索引。

    不使用索引:

 SELECT ACCOUNT_NAME,AMOUNT
 FROM TRANSACTION
 WHERE ACCOUNT_NAME||ACCOUNT_TYPE=‘AMEXA’;

 使用索引:

 SELECT ACCOUNT_NAME,AMOUNT
 FROM TRANSACTION
 WHERE ACCOUNT_NAME = ‘AMEX’AND ACCOUNT_TYPE=‘ A’;

 下面的例子中, ‘+’是数学函数。 就象其他数学函数那样, 停用了索引。

    不使用索引:

 SELECT ACCOUNT_NAME, AMOUNT
 FROM TRANSACTION
 WHERE AMOUNT + 3000 >5000;

 使用索引:

 SELECT ACCOUNT_NAME, AMOUNT
 FROM TRANSACTION
 WHERE AMOUNT > 2000 ;

 下面的例子中,相同的索引列不能互相比较,这将会启用全表扫描。

    不使用索引:

 SELECT ACCOUNT_NAME, AMOUNT
 FROM TRANSACTION
 WHERE ACCOUNT_NAME = NVL(:ACC_NAME,ACCOUNT_NAME);

 使用索引:

 SELECT ACCOUNT_NAME, AMOUNT
 FROM TRANSACTION
 WHERE ACCOUNT_NAME LIKE NVL(:ACC_NAME,‘%’);

 译者按:如果一定要对使用函数的列启用索引, ORACLE新的功能: 基于函数的索引(Function-Based Index) 也许是一个较好的方案。

    CREATE INDEX EMP_I ON EMP (UPPER(ename)); /*建立基于函数的索引*/
 SELECT * FROM emp WHERE UPPER(ename) = ‘BLACKSNAIL’; /*将使用索引*/

 46.       连接多个扫描

 如果你对一个列和一组有限的值进行比较, 优化器可能执行多次扫描并对结果进行合并连接。

    举例:

 SELECT *
 FROM LODGING
 WHERE MANAGER IN (‘BILL GATES’,‘KEN MULLER’);

 优化器可能将它转换成以下形式

 SELECT *
 FROM LODGING
 WHERE MANAGER = ‘BILL GATES’OR MANAGER = ‘KEN MULLER’;

 当选择执行路径时, 优化器可能对每个条件采用LODGING$MANAGER上的索引范围扫描。 返回的ROWID用来访问LODGING表的记录 (通过TABLE ACCESS BY ROWID 的方式)。 最后两组记录以连接(CONCATENATION)的形式被组合成一个单一的集合。

    Explain Plan :
 SELECT STATEMENT Optimizer=CHOOSE
 CONCATENATION
  TABLE ACCESS (BY INDEX ROWID) OF LODGING
   INDEX (RANGE SCAN ) OF LODGING$MANAGER (NON-UNIQUE)
     TABLE ACCESS (BY INDEX ROWID) OF LODGING
   INDEX (RANGE SCAN ) OF LODGING$MANAGER (NON-UNIQUE)

    译者按:本节和第37节似乎有矛盾之处。

    47.       CBO下使用更具选择性的索引

 基于成本的优化器(CBO, Cost-Based Optimizer)对索引的选择性进行判断来决定索引的使用是否能提高效率。

    如果索引有很高的选择性, 那就是说对于每个不重复的索引键值,只对应数量很少的记录。

    比如, 表中共有100条记录而其中有80个不重复的索引键值。 这个索引的选择性就是80/100 = 0.8 . 选择性越高, 通过索引键值检索出的记录就越少。

    如果索引的选择性很低, 检索数据就需要大量的索引范围查询操作和ROWID 访问表的操作。 也许会比全表扫描的效率更低。

    译者按:

 下列经验请参阅:

 a.       如果检索数据量超过30%的表中记录数。使用索引将没有显著的效率提高。
    b.       在特定情况下, 使用索引也许会比全表扫描慢, 但这是同一个数量级上的区别。 而通常情况下,使用索引比全表扫描要快几倍乃至几千倍!

    48.       避免使用耗费资源的操作

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

    例如,一个UNION查询,其中每个查询都带有GROUP BY子句, GROUP BY会触发嵌入排序(NESTED SORT) ; 这样, 每个查询需要执行一次排序, 然后在执行UNION时, 又一个唯一排序(SORT UNIQUE)操作被执行而且它只能在前面的嵌入排序结束后才能开始执行。 嵌入的排序的深度会大大影响查询的效率。

    通常, 带有UNION, MINUS , INTERSECT的SQL语句都可以用其他方式重写。

    译者按:如果你的数据库的SORT_AREA_SIZE调配得好, 使用UNION , MINUS, INTERSECT也是可以考虑的, 毕竟它们的可读性很强

49.       优化GROUP BY

 提高GROUP BY 语句的效率, 可以通过将不需要的记录在GROUP BY 之前过滤掉。下面两个查询返回相同结果但第二个明显就快了许多。

    低效:

 SELECT JOB , AVG(SAL)
    FROM EMP
 GROUP by JOB
 HAVING JOB = ‘PRESIDENT’
 OR JOB = ‘MANAGER’

 高效:

 SELECT JOB , AVG(SAL)
    FROM EMP
 WHERE JOB = ‘PRESIDENT’
 OR JOB = ‘MANAGER’GROUP by JOB

 译者按:本节和14节相同。 可略过。

    50.       使用日期当

 使用日期是,需要注意如果有超过5位小数加到日期上, 这个日期会进到下一天!

    例如:

 1.

 SELECT TO_DATE(‘01-JAN-93’+.99999)
    FROM DUAL;
 Returns:“01-JAN-93 23:59:59‘

 2.

 SELECT TO_DATE(’01-JAN-93‘+.999999)
    FROM DUAL;
    Returns:“02-JAN-93 00:00:00‘

 译者按:虽然本节和SQL性能优化没有关系, 但是作者的功力可见一斑

 51.   使用显式的游标(CURSORs)

    使用隐式的游标,将会执行两次操作。 第一次检索记录, 第二次检查TOO MANY ROWS 这个exception . 而显式游标不执行第二次操作。

    52.   优化EXPORT和IMPORT

 使用较大的BUFFER(比如10MB , 10,240,000)可以提高EXPORT和IMPORT的速度。

    ORACLE将尽可能地获取你所指定的内存大小,即使在内存不满足,也不会报错。这个值至少要和表中最大的列相当,否则列值会被截断。

    译者按:可以肯定的是, 增加BUFFER会大大提高EXPORT , IMPORT的效率。 (曾经碰到过一个CASE, 增加BUFFER后,IMPORT/EXPORT快了10倍!)

    作者可能犯了一个错误: “这个值至少要和表中最大的列相当,否则列值会被截断。 ”其中最大的列也许是指最大的记录大小。

    关于EXPORT/IMPORT的优化,CSDN论坛中有一些总结性的贴子,比如关于BUFFER参数, COMMIT参数等等, 详情请查。

    53.   分离表和索引

 总是将你的表和索引建立在不同的表空间内(TABLESPACES)。 决不要将不属于ORACLE内部系统的对象存放到SYSTEM表空间里。 同时,确保数据表空间和索引表空间置于不同的硬盘上。

    译者按:“同时,确保数据表空间和索引表空间置与不同的硬盘上。”可能改为如下更为准确 “同时,确保数据表空间和索引表空间置与不同的硬盘控制卡控制的硬盘上。”
分享到:
评论

相关推荐

    智能车竞赛介绍(竞赛目标和赛程安排).zip

    全国大学生智能汽车竞赛自2006年起,由教育部高等教育司委托高等学校自动化类教学指导委员会举办,旨在加强学生实践、创新能力和培养团队精神的一项创意性科技竞赛。该竞赛至今已成功举办多届,吸引了众多高校学生的积极参与,此文件为智能车竞赛介绍

    集字卡v4.3.4微信公众号原版三种UI+关键字卡控制+支持强制关注.zip

    字卡v4.3.4 原版 三种UI+关键字卡控制+支持获取用户信息+支持强制关注 集卡模块从一开始的版本到助力版本再到现在的新规则版本。 集卡模块难度主要在于 如何控制各种不同的字卡组合 被粉丝集齐的数量。 如果不控制那么一定会出现超过数量的粉丝集到指定的字卡组合,造成奖品不够的混乱,如果大奖价值高的话,超过数量的粉丝集到大奖后,就造成商家的活动费用超支了。我们冥思苦想如何才能限制集到指定字卡组合的粉丝数,后我们想到了和支付宝一样的选一张关键字卡来进行规则设置的方式来进行限制,根据奖品所需的关键字卡数,设定规则就可以控制每种奖品所需字卡组合被粉丝集到的数量,规则可以在活动进行中根据需要进行修改,活动规则灵活度高。新版的集卡规则,在此次政府发布号的活动中经受了考验,集到指定字卡组合的粉丝没有超出规则限制。有了这个规则限制后,您无需盯着活动,建好活动后就无人值守让活动进行就行了,您只需要时不时来看下蹭蹭上涨的活动数据即可。 被封? 无需担心,模块内置有防封功能,支持隐藏主域名,显示炮灰域名,保护活动安全进行。 活动准备? 只需要您有一个认证服务号即可,支持订阅号借用认证服务号来做活动。如果您

    出口设备线体程序详解:PLC通讯下的V90控制与开源FB284工艺对象实战指南,出口设备线体程序详解:PLC通讯与V90控制集成,工艺对象与FB284协同工作,开源学习V90控制技能,出口设备1200

    出口设备线体程序详解:PLC通讯下的V90控制与开源FB284工艺对象实战指南,出口设备线体程序详解:PLC通讯与V90控制集成,工艺对象与FB284协同工作,开源学习V90控制技能,出口设备1200线体程序,多个plc走通讯,内部有多个v90,采用工艺对象与fb284 共同控制,功能快全部开源,能快速学会v90的控制 ,出口设备; 1200线体程序; PLC通讯; 多个V90; 工艺对象; FB284; 功能开源; V90控制。,V90工艺控制:开源功能快,快速掌握1200线体程序与PLC通讯

    基于Arduino与DAC8031的心电信号模拟器资料:心电信号与正弦波的双重输出应用方案,Arduino与DAC8031心电信号模拟器:生成心电信号与正弦波输出功能详解,基于arduino +DAC

    基于Arduino与DAC8031的心电信号模拟器资料:心电信号与正弦波的双重输出应用方案,Arduino与DAC8031心电信号模拟器:生成心电信号与正弦波输出功能详解,基于arduino +DAC8031的心电信号模拟器资料,可输出心电信号,和正弦波 ,基于Arduino;DAC8031;心电信号模拟器;输出心电信号;正弦波输出;模拟器资料,基于Arduino与DAC8031的心电信号模拟器:输出心电与正弦波

    (参考项目)MATLAB口罩识别检测.zip

    MATLAB口罩检测的基本流程 图像采集:通过摄像头或其他图像采集设备获取包含面部的图像。 图像预处理:对采集到的图像进行灰度化、去噪、直方图均衡化等预处理操作,以提高图像质量,便于后续的人脸检测和口罩检测。 人脸检测:利用Haar特征、LBP特征等经典方法或深度学习模型(如MTCNN、FaceBoxes等)在预处理后的图像中定位人脸区域。 口罩检测:在检测到的人脸区域内,进一步分析是否佩戴口罩。这可以通过检测口罩的边缘、纹理等特征,或使用已经训练好的口罩检测模型来实现。 结果输出:将检测结果以可视化方式展示,如在图像上标注人脸和口罩区域,或输出文字提示是否佩戴口罩。

    kernel-debug-devel-3.10.0-1160.119.1.el7.x64-86.rpm.tar.gz

    1、文件内容:kernel-debug-devel-3.10.0-1160.119.1.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/kernel-debug-devel-3.10.0-1160.119.1.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、更多资源/技术支持:公众号禅静编程坊

    day02供应链管理系统-补充.zip

    该文档提供了一个关于供应链管理系统开发的详细指南,重点介绍了项目安排、技术实现和框架搭建的相关内容。 文档分为以下几个关键部分: 项目安排:主要步骤包括搭建框架(1天),基础数据模块和权限管理(4天),以及应收应付和销售管理(5天)。 供应链概念:供应链系统的核心流程是通过采购商品放入仓库,并在销售时从仓库提取商品,涉及三个主要订单:采购订单、销售订单和调拨订单。 大数据的应用:介绍了数据挖掘、ETL(数据抽取)和BI(商业智能)在供应链管理中的应用。 技术实现:讲述了DAO(数据访问对象)的重用、服务层的重用、以及前端JS的继承机制、jQuery插件开发等技术细节。 系统框架搭建:包括Maven环境的配置、Web工程的创建、持久化类和映射文件的编写,以及Spring配置文件的实现。 DAO的需求和功能:供应链管理系统的各个模块都涉及分页查询、条件查询、删除、增加、修改操作等需求。 泛型的应用:通过示例说明了在Java语言中如何使用泛型来实现模块化和可扩展性。 文档非常技术导向,适合开发人员参考,用于构建供应链管理系统的架构和功能模块。

    基于四旋翼无人机的PD控制研究 附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    C#与VB实现欧姆龙PLC的Fins TCP通信案例源码:调用动态链接库进行数据读写,定时器与计数器数据区的简洁读写操作示例,C#与VB实现欧姆龙PLC的Fins TCP通信案例源码:调用动态链接库进

    C#与VB实现欧姆龙PLC的Fins TCP通信案例源码:调用动态链接库进行数据读写,定时器与计数器数据区的简洁读写操作示例,C#与VB实现欧姆龙PLC的Fins TCP通信案例源码:调用动态链接库进行读写操作,涵盖定时器计数器数据区学习案例,C#欧姆龙plc Fins Tcp通信案例上位机源码,有c#和VB的Demo,c#上位机和欧姆龙plc通讯案例源码,调用动态链接库,可以实现上位机的数据连接,可以简单实现D区W区定时器计数器等数据区的读写,是一个非常好的学习案例 ,C#; 欧姆龙PLC; Fins Tcp通信; 上位机源码; 动态链接库; 数据连接; D区W区读写; 定时器计数器; 学习案例,C#实现欧姆龙PLC Fins Tcp通信上位机源码,读写数据区高效学习案例

    可调谐石墨烯超材料吸收体的FDTD仿真模拟研究报告:吸收光谱的化学势调节策略与仿真源文件解析,可调谐石墨烯超材料吸收体:化学势调节光谱的FDTD仿真模拟研究,可调谐石墨烯超材料吸收体FDTD仿真模拟

    可调谐石墨烯超材料吸收体的FDTD仿真模拟研究报告:吸收光谱的化学势调节策略与仿真源文件解析,可调谐石墨烯超材料吸收体:化学势调节光谱的FDTD仿真模拟研究,可调谐石墨烯超材料吸收体FDTD仿真模拟 【案例内容】该案例提供了一种可调谐石墨烯超材料吸收体,其吸收光谱可以通过改变施加于石墨烯的化学势来进行调节。 【案例文件】仿真源文件 ,可调谐石墨烯超材料吸收体; FDTD仿真模拟; 化学势调节; 仿真源文件,石墨烯超材料吸收体:FDTD仿真调节吸收光谱案例解析

    RBF神经网络控制仿真-第二版

    RBF神经网络控制仿真-第二版

    松下PLC与威纶通触摸屏转盘设备控制:FPWINPRO7与EBPRO智能编程与宏指令应用,松下PLC与威纶通触摸屏转盘设备控制解决方案:FPWINPRO7与EBPRO协同工作,实现多工位转盘加工与IE

    松下PLC与威纶通触摸屏转盘设备控制:FPWINPRO7与EBPRO智能编程与宏指令应用,松下PLC与威纶通触摸屏转盘设备控制解决方案:FPWINPRO7与EBPRO协同工作,实现多工位转盘加工与IEC编程模式控制,松下PLC+威纶通触摸屏的转盘设备 松下PLC工程使用程序版本为FPWINPRO7 7.6.0.0版本 威纶通HMI工程使用程序版本为EBPRO 6.07.02.410S 1.多工位转盘加工控制。 2.国际标准IEC编程模式。 3.触摸屏宏指令应用控制。 ,松下PLC; 威纶通触摸屏; 转盘设备控制; 多工位加工控制; IEC编程模式; 触摸屏宏指令应用,松下PLC与威纶通HMI联控的转盘设备控制程序解析

    基于循环神经网络(RNN)的多输入单输出预测模型(适用于时间序列预测与回归分析,需Matlab 2021及以上版本),基于循环神经网络(RNN)的多输入单输出预测模型(matlab版本2021+),真

    基于循环神经网络(RNN)的多输入单输出预测模型(适用于时间序列预测与回归分析,需Matlab 2021及以上版本),基于循环神经网络(RNN)的多输入单输出预测模型(matlab版本2021+),真实值与预测值对比,多种评价指标与线性拟合展示。,RNN预测模型做多输入单输出预测模型,直接替数据就可以用。 程序语言是matlab,需求最低版本为2021及以上。 程序可以出真实值和预测值对比图,线性拟合图,可打印多种评价指标。 PS:以下效果图为测试数据的效果图,主要目的是为了显示程序运行可以出的结果图,具体预测效果以个人的具体数据为准。 2.由于每个人的数据都是独一无二的,因此无法做到可以任何人的数据直接替就可以得到自己满意的效果。 这段程序主要是一个基于循环神经网络(RNN)的预测模型。它的应用领域可以是时间序列预测、回归分析等。下面我将对程序的运行过程进行详细解释和分析。 首先,程序开始时清空环境变量、关闭图窗、清空变量和命令行。然后,通过xlsread函数导入数据,其中'数据的输入'和'数据的输出'是两个Excel文件的文件名。 接下来,程序对数据进行归一化处理。首先使用ma

    【图像识别】手写文字识别研究 附Matlab代码+运行结果.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    旅游管理系统(基于springboot,mysql,java).zip

    旅游管理系统中的功能模块主要是实现管理员;首页、个人中心、用户管理、旅游方案管理、旅游购买管理、系统管理,用户;首页、个人中心、旅游方案管理、旅游购买管理、我的收藏管理。前台首页;首页、旅游方案、旅游资讯、个人中心、后台管理等功能。经过认真细致的研究,精心准备和规划,最后测试成功,系统可以正常使用。分析功能调整与旅游管理系统实现的实际需求相结合,讨论了Java开发旅游管理系统的使用。 从上面的描述中可以基本可以实现软件的功能: 1、开发实现旅游管理系统的整个系统程序;  2、管理员;首页、个人中心、用户管理、旅游方案管理、旅游购买管理、系统管理等。 3、用户:首页、个人中心、旅游方案管理、旅游购买管理、我的收藏管理。 4、前台首页:首页、旅游方案、旅游资讯、个人中心、后台管理等相应操作; 5、基础数据管理:实现系统基本信息的添加、修改及删除等操作,并且根据需求进行交流查看及回复相应操作。

    Boost二级升压光伏并网结构的Simulink建模与MPPT最大功率点追踪:基于功率反馈的扰动观察法调整电压方向研究,Boost二级升压光伏并网结构的Simulink建模与MPPT最大功率点追踪:基

    Boost二级升压光伏并网结构的Simulink建模与MPPT最大功率点追踪:基于功率反馈的扰动观察法调整电压方向研究,Boost二级升压光伏并网结构的Simulink建模与MPPT最大功率点追踪:基于功率反馈的扰动观察法调整电压方向研究,Boost二级升压光伏并网结构,Simulink建模,MPPT最大功率点追踪,扰动观察法采用功率反馈方式,若ΔP>0,说明电压调整的方向正确,可以继续按原方向进行“干扰”;若ΔP<0,说明电压调整的方向错误,需要对“干扰”的方向进行改变。 ,Boost升压;光伏并网结构;Simulink建模;MPPT最大功率点追踪;扰动观察法;功率反馈;电压调整方向。,光伏并网结构中Boost升压MPPT控制策略的Simulink建模与功率反馈扰动观察法

    基于matlab平台的图像去雾设计.zip

    运行GUI版本,可二开

    Deepseek相关参考资源文档

    Deepseek相关主题资源及行业影响

    WP Smush Pro3.16.12 一款专为 WordPress 网站设计的图像优化插件开心版.zip

    WP Smush Pro 是一款专为 WordPress 网站设计的图像优化插件。 一、主要作用 图像压缩 它能够在不影响图像质量的前提下,大幅度减小图像文件的大小。例如,对于一些高分辨率的产品图片或者风景照片,它可以通过先进的压缩算法,去除图像中多余的数据。通常 JPEG 格式的图像经过压缩后,文件大小可以减少 40% – 70% 左右。这对于网站性能优化非常关键,因为较小的图像文件可以加快网站的加载速度。 该插件支持多种图像格式的压缩,包括 JPEG、PNG 和 GIF。对于 PNG 图像,它可以在保留透明度等关键特性的同时,有效地减小文件尺寸。对于 GIF 图像,也能在一定程度上优化文件大小,减少动画 GIF 的加载时间。 懒加载 WP Smush Pro 实现了图像懒加载功能。懒加载是一种延迟加载图像的技术,当用户滚动页面到包含图像的位置时,图像才会加载。这样可以避免一次性加载大量图像,尤其是在页面内容较多且包含许多图像的情况下。例如,在一个新闻网站的长文章页面,带有大量配图,懒加载可以让用户在浏览文章开头部分时,不需要等待所有图片加载,从而提高页面的初始加载速度,同时也能

    1. Download this file: https://cdn-media.huggingface.co/frpc-gradio-0.3/frpc-windows-amd64.exe

    Could not create share link. Missing file: C:\Users\xx\.conda\envs\omni\Lib\site-packages\gradio\frpc_windows_amd64_v0.3 1. Download this file: https://cdn-media.huggingface.co/frpc-gradio-0.3/frpc_windows_amd64.exe 2. Rename the downloaded file to: frpc_windows_amd64_v0.3 3. Move the file to this location: C:\Users\xx\.conda\envs\omni\Lib\site-packages\gradio

Global site tag (gtag.js) - Google Analytics