Sql oracle中列的一部分中的索引?

Sql oracle中列的一部分中的索引?,sql,oracle,indexing,Sql,Oracle,Indexing,在oracle中:我有一个包含这些列(object_id1,object_id2)的表rel,它关联系统中的对象对。对象ID是varchar,前3个字符标识对象的类型。例如,用户从001开始,书籍从002开始,但还有更多类型。现在,我想获取此表中与此查询相关的所有用户手册对: SELECT * FROM rel WHERE rel.object_id1 LIKE '001%' AND rel.object_id2 LIKE '002%' 为此,我需要在object_id1和object_id2

在oracle中:我有一个包含这些列(object_id1,object_id2)的表rel,它关联系统中的对象对。对象ID是varchar,前3个字符标识对象的类型。例如,用户从001开始,书籍从002开始,但还有更多类型。现在,我想获取此表中与此查询相关的所有用户手册对:

SELECT * FROM rel WHERE rel.object_id1 LIKE '001%' AND rel.object_id2 LIKE '002%'

为此,我需要在object_id1和object_id2的前三个字符上建立一个b树索引。是否可以在列的某一部分(在本例中为前3个字符)上建立索引?如何实现?

您可以使用基于函数的索引来实现这一点

假设:

SQL> create table t (a varchar(10));
Table created.
然后可以在该列的前三个字符上创建索引:

SQL> create index t_s on t(substr(a,0,3));
Index created.
如果在查询中使用完全相同的函数,则将使用该函数:

SQL> set autotrace traceonly;
SQL> select * from t where SUBSTR(a,0,3) = '001' ;

no rows selected


Execution Plan
----------------------------------------------------------
Plan hash value: 2699450933

------------------------------------------------------------------------------------
| Id  | Operation           | Name | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |      |     1 |     7 |     1   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T    |     1 |     7 |     1   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN      | T_S  |     1 |       |     1   (0)| 00:00:01 |
------------------------------------------------------------------------------------
...

如果无法更改物理模式以将对象类型值放在单独的列中(最有效的方法),则可以使用SUBSTR函数在子字符串上创建基于函数的索引,如:

在rel(SUBSTR(object_id1,1,3))上创建索引rel_idx_f01


显然,您需要为每个object_id1和object_id2列创建一个索引。

您可以创建一个基于函数的索引

CREATE INDEX idx_rel_obj_id
   ON( substr( object_id1, 1, 3 ),
       substr( object_id2, 1, 3 ) );
但是,您的查询将需要使用相同的函数调用

SELECT *
  FROM rel
 WHERE substr( rel.object_id1, 1, 3 ) = '001'
   AND substr( rel.object_id2, 1, 3 ) = '002'
通常,您将创建用户定义的函数(即get_object_type)标记为确定性的,将在索引定义和查询中使用这些用户定义函数,以确保不会有人无意中使用不同的构造来获取字段的前三个字符,从而阻止使用基于函数的索引

尽管如此,在表中有一列,其中前三个字符表示其他数据元素,这违反了基本的规范化。您最好将前三个字符存储在单独的列中,而不是在运行时尝试解析复合列