请教Oracel高手一个问题,谢谢(50分)

  • 主题发起人 主题发起人 ggwen
  • 开始时间 开始时间
G

ggwen

Unregistered / Unconfirmed
GUEST, unregistred user!
Oracel书上在讲到用外连接代替‘Not in’时有个例子(说这样可以加快查询速度)
select A.Name,Loding
from Worker A
where A.Name not in
(Select Name from WorekerSkill where Skill='SMITHY')

select A.Name,Lodging
from Worker A,Workersskill b
where A.Name=B.Name(+)
and B.Name is null
and B.Skill(+)='SMITHY'

我想知道第二个SQL语句,where后面条件的执行顺序,是从前往后,
还是从后往前,还是有编译器分析决定?
为了提高查询效率,where后面条件的书写应遵循什么原则?把苛刻条件往前放,还是往后放?

First,Thanks very much!
 
一般是从左往右执行的, 当然先执行的是括号括起来的, 就和普通的运算一样的.
然后就要看一看运算的优先级

一般来说,
1. 将同表的比较放在前面, 比如: where a.id=a.eid and a.id=b.id
2. 将经常出现true的比较方在前面, 比如: where a.name='sss' or a.worktime>8
3. 将整数, 常量的比较放在前面, 比如: where a.id<123 and a.sex='M' and a.age>b.agelimit
4. 将传参数的比较放在较后面, 比如: where a.id>1 and a.age>:age
5. 将字段尽量按照建表时的先后次序比较

1~5优先级依次降低, 满足条件多的放在前面, 当然也可以加括号调整优先级
 
有两个问题请教 Iknow
1。如果按照从左向右的顺序执行,那么第二个sql语句我搞不懂,先执行A.Name=B.Name,
那么所过滤出的集合中就不会包含B.Name is null的记录,只有先执行A.Name=B.Name了
后再执行B.Skill(+)=Smith后才会出现B.Name is null的记录,请多指教!
2.第二个问题:一个数据量大的表和一个数据量小的表,在Select语句中,大表在前还是
小表在前,请多指教!

 
1。如果两个条件(或表)是同一个子查询的话,苛刻条件(小表)放前面
2。如果是多级的,苛刻条件当然是放在后面,它会先作,减少中间表的数据量
3。一般来说效率比较: 外连接 > not in > in ,in 的效率是很差的,
oracle 建议不到万不得已不要用。
 
我有一个问题,你写的两个 sql 是从书上抄下来的吗?

第二个 sql and B.Skill(+)='SMITHY' 中 (+) 没有一点意义啊,
去掉之后(直接用 and B.Skill = 'SMITHY' )提高了效率,
而且结果也和第一句一样。

//没有测试过,说错了多包涵
 
对不起,今天又看了一下,发现有一个地方搞反了,应该是:

外连接 > IN > NOT IN, NOT IN 效率最低,ORACLE 建议能不用就不用

可以想一想其中的道理:

外连接只做一次查询,IN 和 NOT IN 必须做两次查询,
IN 查询时只要在子查询的中间表中遇到第一个就可以返回了,
而 NOT IN 必须遍历整个子查询中间表。

 
多人接受答案了。
 
后退
顶部