order by 使用索引的情况

系统 2182 0
order by使用索引 要保证那个列设置为非空

以下只在oracle10g中测试:

order by 使用索引是有条件的(只包括在有选择的此列上,不一定适应*的情况):

1)ORDER BY中所有的列必须包含在相同的索引中并保持在索引中的排列顺序.
2)ORDER BY中所有的列必须定义为非空.

请看下面的测试:

id为PK,a上有一般索引,b列没有索引

执行下面两条语句,结果是先order by ,再执行rownum<20

(1)select * from tb where rownum<20 order by id;

但如果是这样:

(2)select * from tb where rownum<20 order by b;

(3) select * from tb where rownum<20 order by a;

结果是先执行rownum<7,再order by

这是为什么呢,跟主健及其上面的索引有关系:

再看看下面的测试:----------------------------------------------------------------------------------------------------------

ID是主健.

SQL> select * from t;

        ID        ID1
---------- ----------
         1          2
         2          4
         4          3


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   TABLE ACCESS (FULL) OF 'T'

SQL> select * from t where rownum<3 order by id desc;

        ID        ID1
---------- ----------
         4          3
         2          4


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   COUNT (STOPKEY)
   2    1     TABLE ACCESS (BY INDEX ROWID) OF 'T'
   3    2       INDEX (FULL SCAN DESCENDING) OF 'PK' (UNIQUE)
'因为是主健,先进行索引的排序全表扫描,然后在count 2'

SQL> select * from t where rownum<3 order by id1;

        ID        ID1
---------- ----------
         1          2
         2          4


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   SORT (ORDER BY)
   2    1     COUNT (STOPKEY)
   3    2       TABLE ACCESS (FULL) OF 'T'
'没有使用索引,先进行全表扫描,然后再count 2,再排序'

为什么会使用pk的索引呢?一般的索引行吗?
我们看看:

1)在id1上创建索引


SQL> create index id1idx on t(id1);

索引已创建。
SQL> select * from t where rownum<3 order by id1;

        ID        ID1
---------- ----------
         1          2
         2          4


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   SORT (ORDER BY)
   2    1     COUNT (STOPKEY)
   3    2       TABLE ACCESS (FULL) OF 'T' '还是全表扫描'

SQL> select * from t where id1>0 and rownum<3 order by id1;
'加了id1>0 ,这样会使用到id1的索引'

        ID        ID1
---------- ----------
         1          2
         4          3


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   COUNT (STOPKEY)
   2    1     TABLE ACCESS (BY INDEX ROWID) OF 'T'
   3    2       INDEX (RANGE SCAN) OF 'ID1IDX' (NON-UNIQUE)


2)pk的索引是因为有order by 而使用的。order by 使用索引是有条件的:
ORDER BY中所有的列必须包含在相同的索引中并保持在索引中的排列顺序.
ORDER BY中所有的列必须定义为非空.

因为id1是可以为空的,所以order by 不会使用它。而pk的索引是非空的,所以order by 会使用。

我们将id1设为非空看看。


SQL> alter table t
2 modify (id1 int not null);

表已更改。

SQL> select * from t where rownum<3 order by id1;

        ID        ID1
---------- ----------
         1          2
         4          3


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   COUNT (STOPKEY)
   2    1     TABLE ACCESS (BY INDEX ROWID) OF 'T'
   3    2       INDEX (FULL SCAN) OF 'ID1IDX' (NON-UNIQUE)
'这次,order by id1 使用了id1上的索引!'

说明 如果该表上尚未创建聚集索引,且在创建 PRIMARY KEY 约束时未指定非聚集索引,PRIMARY KEY 约束会自动创建聚集索引。

order by 使用索引的情况


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论