【发布时间】:2011-03-10 04:32:33
【问题描述】:
我有两张桌子:
create table big( id number, name varchar2(100));
insert into big(id, name) select rownum, object_name from all_objects;
create table small as select id from big where rownum < 10;
create index big_index on big(id);
如果我执行以下查询,则在这些表上:
select *
from big_table
where id like '45%'
or id in ( select id from small_table);
它总是用于全表扫描。
Execution Plan
----------------------------------------------------------
Plan hash value: 2290496975
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3737 | 97162 | 85 (3)| 00:00:02 |
|* 1 | FILTER | | | | | |
| 2 | TABLE ACCESS FULL| BIG | 74718 | 1897K| 85 (3)| 00:00:02 |
|* 3 | TABLE ACCESS FULL| SMALL | 1 | 4 | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("ID"=45 OR EXISTS (SELECT /*+ */ 0 FROM "SMALL" "SMALL"
WHERE "ID"=:B1))
3 - filter("ID"=:B1)
有什么方法可以重写查询,使其始终用于索引扫描。
【问题讨论】:
-
这是一个错字 - 认为在数据类型与字符串无关(VARCHAR2 等)的列上使用 LIKE 会出错
-
所以你想要以 45 开头的 id?比如 45、45029 和 451?