Oracle 使用灵活的字符数索引列的一部分

Oracle 使用灵活的字符数索引列的一部分,oracle,performance,indexing,Oracle,Performance,Indexing,我想用如下值为列的一部分编制索引:@aaa/453。这意味着此列中的值由四部分组成,即符号字符/数字。 在我们的查询中,我们只有一个数字部分,所以我们希望在这一部分有一个索引。 每个部分中的字符数是可变的 请帮助我这里有一个示例:表包含与您描述的值相似的值 SQL> create table test (col varchar2(20)); Table created. SQL> insert into test 2 select '@aaa/453' from dua

我想用如下值为列的一部分编制索引:@aaa/453。这意味着此列中的值由四部分组成,即符号字符/数字。 在我们的查询中,我们只有一个数字部分,所以我们希望在这一部分有一个索引。 每个部分中的字符数是可变的


请帮助我这里有一个示例:表包含与您描述的值相似的值

SQL> create table test (col varchar2(20));

Table created.

SQL> insert into test
  2  select '@aaa/453'   from dual union all
  3  select '$bcdxyz/35' from dual union all
  4  select '#gf/203'    from dual;

3 rows created.
为了从表中选择行,一个选项是使用这样的查询:

SQL> select * from test
  2  where regexp_substr(col, '\d+$') = '35';

COL
--------------------
$bcdxyz/35
那么,让我们创建一个基于函数的索引:

SQL> create index i1test on test (regexp_substr(col, '\d+$'));

Index created.
解释计划说什么

SQL> explain plan for
  2  select * from test
  3  where regexp_substr(col, '\d+$') = '35';

Explained.

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------
Plan hash value: 210954056

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

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access( REGEXP_SUBSTR ("COL",'\d+$')='35')

Note
-----
   - dynamic sampling used for this statement (level=2)

18 rows selected.

SQL>

看起来可能会有帮助。试试看,看看它是如何工作的。

下面是一个示例:表中包含的值与您描述的值类似

SQL> create table test (col varchar2(20));

Table created.

SQL> insert into test
  2  select '@aaa/453'   from dual union all
  3  select '$bcdxyz/35' from dual union all
  4  select '#gf/203'    from dual;

3 rows created.
为了从表中选择行,一个选项是使用这样的查询:

SQL> select * from test
  2  where regexp_substr(col, '\d+$') = '35';

COL
--------------------
$bcdxyz/35
那么,让我们创建一个基于函数的索引:

SQL> create index i1test on test (regexp_substr(col, '\d+$'));

Index created.
解释计划说什么

SQL> explain plan for
  2  select * from test
  3  where regexp_substr(col, '\d+$') = '35';

Explained.

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------
Plan hash value: 210954056

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

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access( REGEXP_SUBSTR ("COL",'\d+$')='35')

Note
-----
   - dynamic sampling used for this statement (level=2)

18 rows selected.

SQL>


看起来可能会有帮助。试试看,看看它是如何工作的。

你应该把这三部分分成三列。然后,您可以使用常规索引高效地进行筛选。@GMB它需要在或业务中进行非常多的更改,我们现在无法做到这一点。然后使用regexp\u substr创建计算列并对这些列进行索引。在以后的某个时候,你可能会替换原来的列,并将计算列转换为常规列,甚至可能将原来的列变成计算列,那么:-。顺便问一下:你认为有一天会出现拆分列的情况吗?很容易说,我们知道这是一个可怕的设计,但现在我们无法修复它。我们以后会这样做的,但是有一天你会不会不说同样的话呢?有一次你必须咬紧牙关,通常越快越好。你应该把三部分分成三列。然后,您可以使用常规索引高效地进行筛选。@GMB它需要在或业务中进行非常多的更改,我们现在无法做到这一点。然后使用regexp\u substr创建计算列并对这些列进行索引。在以后的某个时候,你可能会替换原来的列,并将计算列转换为常规列,甚至可能将原来的列变成计算列,那么:-。顺便问一下:你认为有一天会出现拆分列的情况吗?很容易说,我们知道这是一个可怕的设计,但现在我们无法修复它。我们以后会这样做的,但是有一天你会不会不说同样的话呢?有一次你必须咬紧牙关,通常越快越好。谢谢。它工作得很好。请告诉我这个正则表达式是如何工作的?regexp_substrcol,“\d+$”不客气。该表达式返回锚定到col列结尾$的任意数字+位数\d。例如,对于abc$fe42,它将返回42No problem;如果有帮助的话,我很高兴。我认为这个函数也很好用,'SUBSTRcol,INSTRcol',/',-1,1+1'。但我不知道哪一个在性能方面更好,特别是在一个有许多insert的表中?SUBSTR是可以的,是的,而且就大型数据集而言,可能会比正则表达式性能更好。对于不太多的行,regexp看起来更漂亮,并且在不影响性能的情况下更容易理解您正在做的事情。谢谢。它工作得很好。请告诉我这个正则表达式是如何工作的?regexp_substrcol,“\d+$”不客气。该表达式返回锚定到col列结尾$的任意数字+位数\d。例如,对于abc$fe42,它将返回42No problem;如果有帮助的话,我很高兴。我认为这个函数也很好用,'SUBSTRcol,INSTRcol',/',-1,1+1'。但我不知道哪一个在性能方面更好,特别是在一个有许多insert的表中?SUBSTR是可以的,是的,而且就大型数据集而言,可能会比正则表达式性能更好。对于不太多的行,regexp看起来更漂亮,并且在不影响性能的情况下更容易理解您正在做的事情。