关于执行计划,sqlserver 和oracle的一点疑惑
. 索引 执行计划
[解决办法]
这样写就不需要嵌套(Nested Loops)循环了..
select id from table1 where id ='1234'
[解决办法]
为什么会出现嵌套循环才能出结果?
按道理,根据非聚集索引查找到聚集索引,
根据聚集索引直接就找到数据的地址了,干嘛再循环嵌套一次呢?
有一个操作是键查找,因为直接使用的非聚集索引无法找到所有的数据,需要用键查找找到除非聚集索引外的其他列,然后用循环嵌套合并数据
[解决办法]
为什么会出现嵌套循环才能出结果?
按道理,根据非聚集索引查找到聚集索引,
根据聚集索引直接就找到数据的地址了,干嘛再循环嵌套一次呢?
有一个操作是键查找,因为直接使用的非聚集索引无法找到所有的数据,需要用键查找找到除非聚集索引外的其他列,然后用循环嵌套合并数据
[解决办法]
你没发现用的不是聚集索引扫描吗?如果是聚集索引扫描就不会有键查找了,所以不存在这个问题了。Oracle和SQL Server在很多算法方面是不同的。
[解决办法]
对于关系R的每个元组 r 将其与关系S的每个元组 s 在JOIN条件的字段上直接比较并筛选出符合条件的元组。写成伪代码就是:
foreach tuple r ? R do
foreach tuple s ? S do
if ri == sj then add to result
这个是Nested loop join的伪代码,你看懂这个就明白上面为什么要用到Nested loop join了。如果没有上面的非聚集索引扫描只扫描Clustered index的话,就变成Clustered index Scan,那么就可以找到所有数据,不需要做其他操作。
[解决办法]
非聚集索引指向聚集索引的键 没错阿
[解决办法]
他的2个索引类型在MSSQL跟oracle正好是倒过来的,
你仔细看,MSSQL中,createDate是聚集索引,而ID是非聚集索引,而oracle中是createDate是非聚集索引,而ID是聚集索引。
[解决办法]
现在我已经完全理解你的意思了。
没猜错的话,oracle中的脚本你还少给了一行关键的
create index index_createdate on indexTable(CreateDate) nologging;
现在问题就很简单了,
1 oracle是先根据CreateDate查出ID,
2 然后根据每个ID用INDEX UNIQUE SCAN来查出对应的数据行。
LZ你有没有发现这种逻辑跟SQL SERVER的计划给出的逻辑是一模一样的,
换句话说,还是那句话,虽然oracle的计划中没有明确给出nested loop,但是它编程为C/C++后,还是逃不出SmithLiu328给出那段NESTED LOOP伪代码的逻辑,否则oracle怎么取“下一个”ID 然后去做INDEX UNIQUE SCAN呢?