Oracle 使用灵活的字符数索引列的一部分
我想用如下值为列的一部分编制索引:@aaa/453。这意味着此列中的值由四部分组成,即符号字符/数字。 在我们的查询中,我们只有一个数字部分,所以我们希望在这一部分有一个索引。 每个部分中的字符数是可变的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
请帮助我这里有一个示例:表包含与您描述的值相似的值
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看起来更漂亮,并且在不影响性能的情况下更容易理解您正在做的事情。