是不是說 to_char(DA.PHONE)=ACC.PHONE 和  DA.PHONE=to_number(ACC.PHONE) 所用開銷不同??這個需要測試才能知道那個效率高的.

解决方案 »

  1.   

    B,数字的比较比CHAR快,因为数字比较执行的是减法,CHAR要一个字符一个字符减,速度差别很大!
      

  2.   

    Haiwer(海阔天空)也许有道理。DA.PHONE = to_number(:PhoneNum) and DA.PHONE=to_number(ACC.PHONE),格式上就比较一致,如果ORACLE也提供
    类似M$的rushmore优化技术的话,性能就能得到提高。不知您试过
    to_char(DA.PHONE)=:PhoneNum and to_char(DA.PHONE)=ACC.PHONE方式下
    的性能差别没有?这都是瞎猜,静候正确的解答吧。 
      

  3.   

    选A,请看测试
    选A,请看测试
    选A,请看测试
    Create table TYT_YHDA (
    USRID    varchar2(10),
    USRNAME    varchar2(10),
    PHONE    number(10)
    );
    Create table ACC_ACCOUNTS (
    PHONE    number(10),
    BALANCE  number(10,2)
    );
    Create Unique Index I_tyt_yhda on tyt_yhda(phone);
    Create Unique Index I_ACC_ACCOUNTS on ACC_ACCOUNTS(phone);A:
    select DA.USRID, nvl(DA.USRNAME,' '),  nvl(DA.PHONE, ' '),
      nvl(ACC.BALANCE,0)
    from TYT_YHDA DA, ACC_ACCOUNTS ACC
    where DA.PHONE = to_number('1111') and to_char(DA.PHONE)=ACC.PHONE;B:
    select DA.USRID, nvl(DA.USRNAME,' '),  nvl(DA.PHONE, ' '),
      nvl(ACC.BALANCE,0)
    from TYT_YHDA DA, ACC_ACCOUNTS ACC
    where DA.PHONE = to_number('111') and DA.PHONE=to_number(ACC.PHONE)explain plan set statement_id='4321'
    for 
    select DA.USRID, nvl(DA.USRNAME,' '),  nvl(DA.PHONE, ' '),
      nvl(ACC.BALANCE,0)
    from TYT_YHDA DA, ACC_ACCOUNTS ACC
    where DA.PHONE = to_number('111') and DA.PHONE=to_number(ACC.PHONE);select lpad(' ',2*level)||operation||' '||options||' '||object_name q_plan
    from plan_table
    where statement_id='1234'
    connect by prior id = parent_id
        and statement_id = '1234'
      start with id = 1;Q_PLAN
    ------------------------------------------------
      NESTED LOOPS
        TABLE ACCESS BY INDEX ROWID TYT_YHDA
          INDEX UNIQUE SCAN I_TYT_YHDA
        TABLE ACCESS BY INDEX ROWID ACC_ACCOUNTS
          INDEX UNIQUE SCAN I_ACC_ACCOUNTS
        TABLE ACCESS BY INDEX ROWID TYT_YHDA
          INDEX UNIQUE SCAN I_TYT_YHDA
        TABLE ACCESS BY INDEX ROWID ACC_ACCOUNTS
          INDEX UNIQUE SCAN I_ACC_ACCOUNTSselect lpad(' ',2*level)||operation||' '||options||' '||object_name q_plan
    from plan_table
    where statement_id='4321'
    connect by prior id = parent_id
        and statement_id = '4321'
      start with id = 1;
    Q_PLAN
    ---------------------------------------------
        TABLE ACCESS BY INDEX ROWID TYT_YHDA
          INDEX UNIQUE SCAN I_TYT_YHDA
        FILTER
          TABLE ACCESS FULL ACC_ACCOUNTS
      MERGE JOIN
        TABLE ACCESS BY INDEX ROWID TYT_YHDA
          INDEX UNIQUE SCAN I_TYT_YHDA
        FILTER
          TABLE ACCESS FULL ACC_ACCOUNTS检查发现,A俩个表上都使用索引,B中,ACC上会是Full Scan
      

  4.   

    我查过ORACLE的资料,说如果查询的字段已建立索引,将只对索引表进行SCAN,而不用对原表进行SCAN,看来答案只能是A好一些了!
      

  5.   

    CSDN真是人才济济,不服不行。
    偶上来看下才大吃一惊。UP一下,让大家看看。
      

  6.   

    看来真的错了,不过请问Dainy(方程式)有没有试过:select DA.USRID, nvl(DA.USRNAME,' '),  nvl(DA.PHONE, ' '),
      MCM_SSHF(DA.USRID),
      nvl(ACC.BALANCE,0)
    from TYT_YHDA DA, ACC_ACCOUNTS ACC
    where DA.PHONE = to_number(:PhoneNum) and ACC.PHONE=:PhoneNum感觉上这一句效率最高,因为两个表都是和常量比较!
    还有,我对ORACLE一窍不通,以上语句如果有语法错误请包涵,帮我改对!谢谢!
      

  7.   

    我选A,可以减少系统开销(ACC数据量大的时候选A,ACC数据量小的时候选B),,
      

  8.   

    我选A,可以减少系统开销(ACC数据量大的时候选A,ACC数据量小的时候选B),
      

  9.   


    To :Haiwer(海阔天空):
    你很细心。
    你的这句:
      where DA.PHONE = to_number(:PhoneNum) and ACC.PHONE=:PhoneNum
    当然要比
      where DA.PHONE = to_number(:PhoneNum) and DA.PHONE=ACC.PHONE
    这句效率高。只是我在前面说过,我的这句SQL语句是从一个大的SQL语句中截选部分出来的,原句在ACC.PHONE处有个外连接:and DA.PHONE=ACC.PHONE(+)。所以才会导致出我们现在讨论的问题。这里面的高手真的很多。正确答案已经出来了,而且回答的很好。Thanks everyone.
      

  10.   

    to:Dainy(方程式) 
    试试能不能写成:
    where DA.PHONE = to_number(:PhoneNum) and ACC.PHONE(+) = :PhoneNum
      

  11.   

    To :Haiwer(海阔天空):
    你的方法也已试过,执行速度也比较慢。
      

  12.   

    这个问题看来是这样,
    当你用外连接的时候,最快的是
    where DA.PHONE = to_number(:PhoneNum) and DA.PHONE=to_number(ACC.PHONE(+))
                                                                  ^^这里不知道语法对不对当你不是用外连接的时候,最快的是
    where DA.PHONE = to_number(:PhoneNum) and ACC.PHONE = :PhoneNum这是因为外连接使得ACC.PHONE的索引怎么都用不到!而你的问题给改成不是外连接后,索引问题对效率的影响大于其他方面.我这也是瞎猜的,公布答案吧!
      

  13.   

    我会选择B,num的查询速度应该比char快。但一开始就注意优化的话,区别不是很大。
      

  14.   


    总结陈词:
    声明我的不见得是正确答案,只是自己在开发过程中的感受,如果不妥请高手多加指教。
    在实际使用中,A的用时不到2s,而B每次都在36s左右,或以上(三个120多万记录的库)。所以正确的应该是A。
    选B的朋友大多提到索引中基于数据类型肯定比字符执行效率高,但正如rwq_(风云浪子)所说:如果查询的字段已建立索引,将只对索引表进行SCAN,而不用对原表进行SCAN,mycode(不写代码)的测试也论证了这点,他的那段测试大家可以看看。在B中,不但对ACC表进行了Full Scan,而且还要进行to_number的转换!这样的效率根本是不能忍受的。这可能让选B的朋友忽略了。
    Haiwer(海阔天空)这句“DA.PHONE=to_number(ACC.PHONE(+))”我先前也曾测试过,会有问题,应该行不通的。(如果有测试成功的请提出)。在这一并也回答了net_steven(吃素的狼) 的那个问题。
    各种方案都已试过。不知大家是否满意?
    另外:早知道有这么高手,有人这么投入,开个100分不算多(虽然不是提问,但佩服嘛)。给分少了,希谅。贵在共同进步。希望大家能交个朋友。
      

  15.   


    总结陈词:
    声明我的不见得是正确答案,只是自己在开发过程中的感受,如果不妥请高手多加指教。在实际使用中,A的用时不到2s,而B每次都在36s左右,或以上(三个120多万记录的库)。所以正确的应该是A。选B的朋友大多提到索引中基于数据类型肯定比字符执行效率高,但正如rwq_(风云浪子)所说:如果查询的字段已建立索引,将只对索引表进行SCAN,而不用对原表进行SCAN,mycode(不写代码)的测试也论证了这点,他的那段测试大家可以看看。在B中,不但对ACC表进行了Full Scan,而且还要进行to_number的转换!这样的效率根本是不能忍受的。这可能让选B的朋友忽略了。Haiwer(海阔天空) 这句“DA.PHONE=to_number(ACC.PHONE(+))”我先前也曾测试过,会有问题,应该行不通的。(如果有测试成功的请提出)。在这一并也回答了net_steven(吃素的狼) 的那个问题。各种方案都已试过。不知大家是否满意?另外:早知道有这么高手,有人这么投入,开个100分不算多(虽然不是提问,但佩服嘛)。给分少了,希谅。贵在共同进步。希望大家能交个朋友。
      

  16.   

    呵呵,這麼好的問題,怎麼沒有看到N_chow的身影
      

  17.   

    select DA.USRID, nvl(DA.USRNAME,' '),  nvl(DA.PHONE, ' '),
      MCM_SSHF(DA.USRID),
      nvl(ACC.BALANCE,0)
    from TYT_YHDA DA, ACC_ACCOUNTS ACC
    where DA.PHONE = to_number(:PhoneNum) and to_char(DA.PHONE)=ACC.PHONE
    改為
    select DA.USRID, nvl(DA.USRNAME,' '),  nvl(DA.PHONE, ' '),
      MCM_SSHF(DA.USRID),
      nvl(ACC.BALANCE,0)
    from TYT_YHDA DA inner join ACC_ACCOUNTS ACC on DA.PHONE = to_number(:PhoneNum) and to_char(DA.PHONE)=ACC.PHONE
    會不會更好?
      

  18.   

    虽然Dainy说a快些,但是也忽略了一个问题查询中where字句一般不应该在"="的
    左边进行运算,而a中则进行了to_char运算。讨论中。