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方式下 的性能差别没有?这都是瞎猜,静候正确的解答吧。
选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
看来真的错了,不过请问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一窍不通,以上语句如果有语法错误请包涵,帮我改对!谢谢!
我选A,可以减少系统开销(ACC数据量大的时候选A,ACC数据量小的时候选B),,
我选A,可以减少系统开销(ACC数据量大的时候选A,ACC数据量小的时候选B),
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.
to:Dainy(方程式) 试试能不能写成: where DA.PHONE = to_number(:PhoneNum) and ACC.PHONE(+) = :PhoneNum
To :Haiwer(海阔天空): 你的方法也已试过,执行速度也比较慢。
这个问题看来是这样, 当你用外连接的时候,最快的是 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的索引怎么都用不到!而你的问题给改成不是外连接后,索引问题对效率的影响大于其他方面.我这也是瞎猜的,公布答案吧!
类似M$的rushmore优化技术的话,性能就能得到提高。不知您试过
to_char(DA.PHONE)=:PhoneNum and to_char(DA.PHONE)=ACC.PHONE方式下
的性能差别没有?这都是瞎猜,静候正确的解答吧。
选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
偶上来看下才大吃一惊。UP一下,让大家看看。
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一窍不通,以上语句如果有语法错误请包涵,帮我改对!谢谢!
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.
试试能不能写成:
where DA.PHONE = to_number(:PhoneNum) and ACC.PHONE(+) = :PhoneNum
你的方法也已试过,执行速度也比较慢。
当你用外连接的时候,最快的是
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的索引怎么都用不到!而你的问题给改成不是外连接后,索引问题对效率的影响大于其他方面.我这也是瞎猜的,公布答案吧!
总结陈词:
声明我的不见得是正确答案,只是自己在开发过程中的感受,如果不妥请高手多加指教。
在实际使用中,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分不算多(虽然不是提问,但佩服嘛)。给分少了,希谅。贵在共同进步。希望大家能交个朋友。
总结陈词:
声明我的不见得是正确答案,只是自己在开发过程中的感受,如果不妥请高手多加指教。在实际使用中,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分不算多(虽然不是提问,但佩服嘛)。给分少了,希谅。贵在共同进步。希望大家能交个朋友。
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
會不會更好?
左边进行运算,而a中则进行了to_char运算。讨论中。