问题1
   我不知道你的主机上的oracle是否支持数据库连,我想应该会支持的,如果支持的话,采用数据库链进行数据传输,我觉得比较好,具体的做法,qq上聊
qq 41080528
问题2:
   建改表的时候加一个选项  cache ,这样把该表强行调入内存中
问题3:
  如果在id上建立索引,查询时,oracle会自动使用索引
问题4:

解决方案 »

  1.   

    1.合理使用索引 
    索引是数据库中重要的数据结构,它的根本目的就是为了提高查询效率。现在大多数的数据库产品都采用IBM最先提出的ISAM索引结构。索引的使用要恰到好处,其使用原则如下: 
    ●在经常进行连接,但是没有指定为外键的列上建立索引,而不经常连接的字段则由优化器自动生成索引。 
    ●在频繁进行排序或分组(即进行group by或order by操作)的列上建立索引。 
    ●在条件表达式中经常用到的不同值较多的列上建立检索,在不同值少的列上不要建立索引。比如在雇员表的“性别”列上只有“男”与“女”两个不同值,因此就无必要建立索引。如果建立索引不但不会提高查询效率,反而会严重降低更新速度。 
    ●如果待排序的列有多个,可以在这些列上建立复合索引(compound index)。 
    ●使用系统工具。如Informix数据库有一个tbcheck工具,可以在可疑的索引上进行检查。在一些数据库服务器上,索引可能失效或者因为频繁操作而使得读取效率降低,如果一个使用索引的查询不明不白地慢下来,可以试着用tbcheck工具检查索引的完整性,必要时进行修复。另外,当数据库表更新大量数据后,删除并重建索引可以提高查询速度。 
    2.避免或简化排序 
    应当简化或避免对大型表进行重复的排序。当能够利用索引自动以适当的次序产生输出时,优化器就避免了排序的步骤。以下是一些影响因素: 
    ●索引中不包括一个或几个待排序的列; 
    ●group by或order by子句中列的次序与索引的次序不一样; 
    ●排序的列来自不同的表。 
    为了避免不必要的排序,就要正确地增建索引,合理地合并数据库表(尽管有时可能影响表的规范化,但相对于效率的提高是值得的)。如果排序不可避免,那么应当试图简化它,如缩小排序的列的范围等。 
    3.消除对大型表行数据的顺序存取 
    在嵌套查询中,对表的顺序存取对查询效率可能产生致命的影响。比如采用顺序存取策略,一个嵌套3层的查询,如果每层都查询1000行,那么这个查询就要查询10亿行数据。避免这种情况的主要方法就是对连接的列进行索引。例如,两个表:学生表(学号、姓名、年龄……)和选课表(学号、课程号、成绩)。如果两个表要做连接,就要在“学号”这个连接字段上建立索引。 
    还可以使用并集来避免顺序存取。尽管在所有的检查列上都有索引,但某些形式的where子句强迫优化器使用顺序存取。下面的查询将强迫对orders表执行顺序操作: 
    SELECT * FROM orders WHERE (customer_num=104 AND order_num>1001) OR order_num=1008 
    虽然在customer_num和order_num上建有索引,但是在上面的语句中优化器还是使用顺序存取路径扫描整个表。因为这个语句要检索的是分离的行的集合,所以应该改为如下语句: 
    SELECT * FROM orders WHERE customer_num=104 AND order_num>1001 
    UNION 
    SELECT * FROM orders WHERE order_num=1008 
    这样就能利用索引路径处理查询。 
    4.避免相关子查询 
    一个列的标签同时在主查询和where子句中的查询中出现,那么很可能当主查询中的列值改变之后,子查询必须重新查询一次。查询嵌套层次越多,效率越低,因此应当尽量避免子查询。如果子查询不可避免,那么要在子查询中过滤掉尽可能多的行。 
    5.避免困难的正规表达式 
    MATCHES和LIKE关键字支持通配符匹配,技术上叫正规表达式。但这种匹配特别耗费时间。例如:SELECT * FROM customer WHERE zipcode LIKE “98_ _ _” 
    即使在zipcode字段上建立了索引,在这种情况下也还是采用顺序扫描的方式。如果把语句改为SELECT * FROM customer WHERE zipcode >“98000”,在执行查询时就会利用索引来查询,显然会大大提高速度。 
    另外,还要避免非开始的子串。例如语句:SELECT * FROM customer WHERE zipcode[2,3] >“80”,在where子句中采用了非开始子串,因而这个语句也不会使用索引。 
    6.使用临时表加速查询 
    把表的一个子集进行排序并创建临时表,有时能加速查询。它有助于避免多重排序操作,而且在其他方面还能简化优化器的工作。例如: 
    SELECT cust.name,rcvbles.balance,……other columns 
    FROM cust,rcvbles 
    WHERE cust.customer_id = rcvlbes.customer_id 
    AND rcvblls.balance>0 
    AND cust.postcode>“98000” 
    ORDER BY cust.name 
    如果这个查询要被执行多次而不止一次,可以把所有未付款的客户找出来放在一个临时文件中,并按客户的名字进行排序: 
    SELECT cust.name,rcvbles.balance,……other columns 
    FROM cust,rcvbles 
    WHERE cust.customer_id = rcvlbes.customer_id 
    AND rcvblls.balance>0 
    ORDER BY cust.name 
    INTO TEMP cust_with_balance 
    然后以下面的方式在临时表中查询: 
    SELECT * FROM cust_with_balance 
    WHERE postcode>“98000” 
    临时表中的行要比主表中的行少,而且物理顺序就是所要求的顺序,减少了磁盘I/O,所以查询工作量可以得到大幅减少。 
    注意:临时表创建后不会反映主表的修改。在主表中数据频繁修改的情况下,注意不要丢失数据。 
    7.用排序来取代非顺序存取 
    非顺序磁盘存取是最慢的操作,表现在磁盘存取臂的来回移动。SQL语句隐藏了这一情况,使得我们在写应用程序时很容易写出要求存取大量非顺序页的查询。 
    有些时候,用数据库的排序能力来替代非顺序的存取能改进查询。
      

  2.   

    优化就是选择最有效的方法来执行SQL语句。Oracle优化器选择它认为最有效的
    方法来执行SQL语句。1. IS NULL和IS NOT NULL
    如果某列存在NULL值,即使对该列建立索引也不会提高性能。
    2. 为不同的工作编写不同的SQL语句块。
    为完成不同的工作编写一大块SQL程序不是好方法。它往往导致每个任务的结果不优
    化。若要SQL完成不同的工作,一般应编写不同的语句块比编写一个要好。
    3. IN 和EXISTS
    Select name from employee where name not in (select name from student);
    Select name from employee where not exists (select name from student);
    第一句SQL语句的执行效率不如第二句。
    通过使用EXISTS,Oracle会首先检查主查询,然后运行子查询直到它找到第一个匹配
    项,这就节省了时间。Oracle在执行IN子查询时,首先执行子查询,并将获得的结果
    列表存放在一个加了索引的临时表中。在执行子查询之前,系统先将主查询挂起,待
    子查询执行完毕,存放在临时表中以后再执行主查询。这也就是使用EXISTS比使用IN
    通常查询速度快的原因。
    4. NOT 运算符
    Select * from employee where salary<>1000;
    Select * from employee where salary<1000 or salary>1000;
    第一句SQL语句的执行效率不如第二句,因为第二句SQL语句可以使用索引。
    5. Order By 语句
    Order By 语句的执行效率很低,因为它要排序。应避免在Order By 字句中使用表达式。
    6. 列的连接
    select * from employee where name||department=’ZYZBIOINFO’;
    select * from employee where name=’ZYZ’ and department=’BIOINFO’;
    这两个查询,第二句比第一句会快,因为对于有连接运算符’||’的查询,Oracle优化器是不
    会使用索引的。
    7. 通配符‘%’当通配符出现在搜索词首时,Oracle优化器不使用索引。
    Select * from employee where name like ‘%Z%’;
    Select * from employee where name like ‘Z%’;
    第二句的执行效率会比第一句快,但查询结果集可能会不同。
    8. 应尽量避免混合类型的表达式。
    假设字段studentno为VARCHAR2类型
    有语句select * from student where studentno>123;
    则Oracle会有一个隐含的类型转换。隐含的类型转换可能会使Oracle优化器忽略索引。
    这时应使用显式的类型转换select * from student where studentno=to_char(123)。
    9.DISTINCT
       DISTINCT总是建立一个排序,所以查询速度也慢。
      

  3.   

    Oracle8i基于规则的优化机制对表达式的处理    goldsun(原作)  
      
    关键字     常量.操作符.传递.确定性 
           ORACLE优化器在任何可能的时候都会对表达式进行评估,并且把特定的语法结构转换成等价的结构,这么做的原因是: 
    ·         要么结果表达式能够比源表达式具有更快的速度·         要么源表达式只是结果表达式的一个等价语义结构不同的SQL结构有时具有同样的操作(例如:= ANY (subquery) and IN (subquery)),ORACLE会把他们映射到一个单一的语义结构。下面将讨论优化器如何评估优化如下的情况和表达式:常量 LIKE 操作符 IN 操作符 ANY和SOME 操作符 ALL 操作符 BETWEEN 操作符 NOT 操作符 传递(Transitivity) 确定性(DETERMINISTIC)函数常量
    常量的计算是在语句被优化时一次性完成,而不是在每次执行时。下面是检索月薪大于2000的的表达式:·         sal > 24000/12·         sal > 2000·         sal*12 > 24000如果SQL语句包括第一种情况,优化器会简单地把它转变成第二种。 注意:优化器不会简化跨越比较符的表达式,例如第三条语句,鉴于此,应用程序开发者应该尽量写用常量跟字段比较检索的表达式,而不要将字段置于表达式当中。LIKE 操作符
    优化器把使用LIKE操作符和一个没有通配符的表达式组成的检索表达式转换为一个“=”操作符表达式。例如:优化器会把表达式ename LIKE 'SMITH'转换为ename = 'SMITH'优化器只能转换涉及到可变长数据类型的表达式,前一个例子中,如果ENAME字段的类型是CHAR(10), 那么优化器将不做任何转换。IN 操作符
    优化器把使用IN比较符的检索表达式替换为等价的使用“=”和“OR”操作符的检索表达式。例如,优化器会把表达式ename IN ('SMITH','KING','JONES')替换为    ename = 'SMITH' OR ename = 'KING' OR ename = 'JONES'ANY和SOME 操作符
    优化器将跟随(following)值列表的ANY和SOME检索条件用等价的同等操作符和“OR”组成的表达式替换。例如,优化器将如下所示的第一条语句用第二条语句替换:·         sal > ANY (:first_sal, :second_sal)·         sal > :first_sal OR sal > :second_sal优化器将跟随子查询的ANY和SOME检索条件转换成由“EXISTS”和一个相应的子查询组成的检索表达式。例如,优化器将如下所示的第一条语句用第二条语句替换:·         x > ANY (SELECT sal FROM emp WHERE job = 'ANALYST')·         EXISTS (SELECT sal FROM emp WHERE job = 'ANALYST' AND x > sal)ALL 操作符
    优化器将跟随值列表的ALL操作符用等价的“=”和“AND”组成的表达式替换。例如,sal > ALL (:first_sal, :second_sal)表达式会被替换为:    sal > :first_sal AND sal > :second_sal 对于跟随子查询的ALL表达式,优化器用ANY和另外一个合适的比较符组成的表达式替换。例如,优化器会把表达式 x > ALL (SELECT sal FROM emp WHERE deptno = 10) 替换为:    NOT (x <= ANY (SELECT sal FROM emp WHERE deptno = 10))接下来优化器会把第二个表达式适用ANY表达式的转换规则转换为下面的表达式:    NOT EXISTS (SELECT sal FROM emp WHERE deptno = 10 AND x <= sal)BETWEEN 操作符
    优化器总是用“>=”和“<=”比较符来等价的代替BETWEEN操作符。例如:优化器会把表达式sal BETWEEN 2000 AND 3000用sal >= 2000 AND sal <= 3000来代替。NOT 操作符
    优化器总是试图简化检索条件以消除“NOT”逻辑操作符的影响,这将涉及到“NOT”操作符的消除以及代以相应的比较运算符。例如,优化器将下面的第一条语句用第二条语句代替:·         NOT deptno = (SELECT deptno FROM emp WHERE ename = 'TAYLOR')·         deptno <> (SELECT deptno FROM emp WHERE ename = 'TAYLOR')通常情况下一个含有NOT操作符的语句有很多不同的写法,优化器的转换原则是使“NOT”操作符后边的子句尽可能的简单,即使可能会使结果表达式包含了更多的“NOT”操作符。例如,优化器将如下所示的第一条语句用第二条语句代替:·         NOT (sal < 1000 OR comm IS NULL)·         NOT sal < 1000 AND comm IS NOT NULL sal >= 1000 AND comm IS NOT NULL传递(Transitivity)
    如果“WHERE”子句的两个检索条件涉及了一个共同的字段,优化器有时会根据传递原理推断出第三个检索条件,随后可以根据这个推断出的条件对语句进行优化,推断出的条件可能会激活一个原来的检索条件没有激活的潜在的接口路径(access path)。注意:传递仅仅被用在基于代价(cost-based)的优化中。假设有一个这样的包含两个检索条件的“WHERE”子句:WHERE 字段1 <comp_oper> 常量 AND字段1 = 字段2,在这个例子里,优化器会推断出新的检索条件:字段2 <comp_oper> 常量。在这里,<comp_oper>是比较运算符=、!=、^=、<>、>、<= 或 >=之中的任何一个,常量是指任何一个涉及了操作符、SQL函数、文字、绑定变量(bind variables)或者关联变量(correlation variables)的常量表达式。例如,考虑这样一个包含两个各自使用了字段EMP.DEPTNO的检索条件的WHERE子句的查询:SELECT * FROM emp, dept WHERE emp.deptno = 20 AND emp.deptno = dept.deptno;使用传递优化,优化器会推断出如下条件:dept.deptno = 20如果有索引存在于EMP.DEPTNO字段上,这个条件会使调用这个索引的接口路径有效。注意:优化器只能对字段关联常量的表达式进行推断,而不是字段关联字段的表达式。例如,包含这样条件的WHERE子句:字段1 <comp_oper> 字段3 AND 字段1 = 字段2,这种情况不能推断出表达式:字段2 < comp_oper> 字段3。确定性(DETERMINISTIC)函数
    在某些情况下,优化器能够使用先前的函数返回结果而不是重新执行用户定义的函数,这仅仅对那些以限制的方式来执行的函数来说是有效的。这些函数必须对任何的输入都有同样的返回值,函数的结果必须不能因为包(PACKAGE)变量、数据库或会话(SESSION)的参数(例如NLS参数)不同而变化,如果函数在将来重新定义,返回值必须对任何参数来说仍然与以前的返回值相同。函数的创建者可以在以CREATE FUNCTION、CREATE PACKAGE或者CREATE TYPE声明函数时根据以上的要求使用DETERMINISTIC关键字向数据库申明该函数为确定性函数,数据库不会对确定性函数的合法性进行校验,即使一个函数明显的使用了包变量或操作了数据库,仍然可以被定义为确定性函数,这就是说如何安全合法的使用和定义确定性函数是程序员的责任。当确定性函数在同一个查询里被多次调用,或者被基于函数的索引或物化视图(materialized view)调用时,有可能被一个已经计算出的值取代
      

  4.   

    谢谢大家的讨论!另一个讨论区:http://expert.csdn.net/Expert/topic/1302/1302580.xml?temp=.2547724
      

  5.   

    问题一:
    不能,
    问题二:
    理论上,根据好象是RUL算法不用强行就可以直接调入内存。
    问题三:
    如果没有ID作为关键字或者没有把ID作为索引的话,是不能的。
    问题四:
    我用过PROC和C+OCI,没有用过你说的方式,无从比较
    问题五:
    我找不到你提的那个帖子。