一般情况下: 有两个表:TABLE_A,TABLE_B SELECT * FROM TABLE_A A WHERE A.ID IN (SELECT B.ID FROM TABLE_B) in()只执行一次,它查出B表中的所有id字段并缓存起来.之后,检查A表的id是否与B表中的id相等,如果相等则将A表的记录加入结果集中,直到遍历完A表的所有记录。IN这种情况适合TABLE_B表比TABLE_A表数据小的情况。 SELECT * FROM TABLE_A A where exists (SELECT 1 FORM TABLE_B B WHERE B.ID = A.ID) exists()会执行TABLE_A.length次,它并不缓存exists()结果集,因为exists()结果集的内容并不重要,重要的是结果集中是否有记录,如果有则返回true,没有则返回false。exists()适合TABLE_B表比TABLE_A表数据大的情况。
打个比方:你有一个过程进行大批量插入 一个游标: cursor c is select * from test where id<=10000 他插入表的时候这语句要进行多少次呢 for i 1:9999 Insert into test1 as select * from test where id=i 个人见解,有点粗陋,可能理解不是很正确
你给表A也加索引,再hint就走索引了 我在A表已经加了索引,也用/*+RULE*/试过了,是不会走索引的,谢谢! 这样 select /*+index(a 索引名)*/* from 表A a
你给表A也加索引,再hint就走索引了 我在A表已经加了索引,也用/*+RULE*/试过了,是不会走索引的,谢谢! 这样 select /*+index(a 索引名)*/* from 表A a …… 我是想要知道上面这两种写法本质上有什么区别,就算从业务来说,也是想要效率更高,那么执着于走一个没必要走的索引干什么…… by the way:那样还是不会走索引的,那是两个字段
我是想说明比如select * from test where id=1 union all select * from test where id=2 union all'''''''''''''''''......................... select * from test where id=10000 和 select * from test where id>=1 and id<=10000 这个COST 是一样的吗?
有两个表:TABLE_A,TABLE_B
SELECT * FROM TABLE_A A WHERE A.ID IN (SELECT B.ID FROM TABLE_B)
in()只执行一次,它查出B表中的所有id字段并缓存起来.之后,检查A表的id是否与B表中的id相等,如果相等则将A表的记录加入结果集中,直到遍历完A表的所有记录。IN这种情况适合TABLE_B表比TABLE_A表数据小的情况。
SELECT * FROM TABLE_A A where exists (SELECT 1 FORM TABLE_B B WHERE B.ID = A.ID)
exists()会执行TABLE_A.length次,它并不缓存exists()结果集,因为exists()结果集的内容并不重要,重要的是结果集中是否有记录,如果有则返回true,没有则返回false。exists()适合TABLE_B表比TABLE_A表数据大的情况。
据我所知,在比较高版本的Oracle中,这两个语句已经优化过了,oracle会自动选择最优情况,跟代码怎么写没关系,事实上,如果只有一个字段(没有or),两种写法执行计划是一样的。而且,在我上面的两种情况里,可以看到执行计划都是对A全扫描,对B走索引,似乎不是这个原因
一个游标:
cursor c is select * from test where id<=10000
他插入表的时候这语句要进行多少次呢
for i 1:9999
Insert into test1 as select * from test where id=i
个人见解,有点粗陋,可能理解不是很正确
我在A表已经加了索引,也用/*+RULE*/试过了,是不会走索引的,谢谢!
可能你们没有仔细看,我这个SQL语句不是一般的exists和in的形式比较,里面有两个字段,通过or连接起来,不是那种情况
比如说要是用到了hash join、bitmap之类,那么确实一次读入全部数据,可以建立某种数据结构,得到与游标不一样的时间复杂度,但是看执行计划,这里好像没有这种情况。如果只是一般的全表扫描,直接读入跟游标的差别可能就是每步初始化的时间不同,时间复杂度应该是一样的吧?但是从执行计划看来,cost差那么远,感觉是时间复杂度不同。
不知道我的理解对否?
我在A表已经加了索引,也用/*+RULE*/试过了,是不会走索引的,谢谢!
这样 select /*+index(a 索引名)*/* from 表A a
我在A表已经加了索引,也用/*+RULE*/试过了,是不会走索引的,谢谢!
这样 select /*+index(a 索引名)*/* from 表A a
……
我是想要知道上面这两种写法本质上有什么区别,就算从业务来说,也是想要效率更高,那么执着于走一个没必要走的索引干什么……
by the way:那样还是不会走索引的,那是两个字段
union all
select * from test where id=2
union all'''''''''''''''''.........................
select * from test where id=10000
和 select * from test where id>=1 and id<=10000 这个COST 是一样的吗?
就是第一种情况是全扫描A表,每一行去跑一次B表的索引;第二次情况是全扫描A表,整体去跑B表的索引,略懂了