用于静态类似子句的Oracle索引

时间:2014-10-02 13:02:37

标签: sql oracle database-performance

我想索引此查询子句 - 请注意该文本是静态的。

SELECT * FROM tbl where flags LIKE '%current_step: complete%'

要重新迭代,current_step: complete永远不会在查询中发生变化。我想构建一个有效预先计算此布尔值的索引,从而阻止全表扫描......

我宁愿不添加布尔列来存储预先计算的值,因为这需要在应用程序中更改代码....

3 个答案:

答案 0 :(得分:3)

如果您不想更改查询,并且这不仅仅是一个问题,也不是更改数据维护(在这种情况下虚拟列和/或索引可以完成工作),您可以使用物化应用过滤器的视图,并让查询重写使用它而不是真实表。这可能是矫枉过正,但是可以选择。

模拟版本的原始计划:

explain plan for
SELECT * FROM tbl where flags LIKE '%current_step: complete%';
select * from table(dbms_xplan.display);

--------------------------------------------------------------------------                                                                                                                                                                                                                                   
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |                                                                                                                                                                                                                                   
--------------------------------------------------------------------------                                                                                                                                                                                                                                   
|   0 | SELECT STATEMENT  |      |     2 |    60 |     3   (0)| 00:00:01 |                                                                                                                                                                                                                                   
|*  1 |  TABLE ACCESS FULL| TBL  |     2 |    60 |     3   (0)| 00:00:01 |                                                                                                                                                                                                                                   
--------------------------------------------------------------------------                                                                                                                                                                                                                                   

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

   1 - filter("FLAGS" IS NOT NULL AND "FLAGS" LIKE '%current_step:                                                                                                                                                                                                                                           
              complete%')                                                                                                                                                                                                                                                                                    

一个物化视图,它只保存您的查询感兴趣的记录(这是一个简单的示例,但您需要决定如何刷新并在需要时添加日志):

create materialized view mvw
enable query rewrite as
SELECT * FROM tbl where flags LIKE '%current_step: complete%';

现在您的查询点击了物化视图,感谢query rewrite

explain plan for
SELECT * FROM tbl where flags LIKE '%current_step: complete%';
select * from table(dbms_xplan.display);

-------------------------------------------------------------------------------------                                                                                                                                                                                                                        
| Id  | Operation                    | Name | Rows  | Bytes | Cost (%CPU)| Time     |                                                                                                                                                                                                                        
-------------------------------------------------------------------------------------                                                                                                                                                                                                                        
|   0 | SELECT STATEMENT             |      |     2 |    60 |     3   (0)| 00:00:01 |                                                                                                                                                                                                                        
|   1 |  MAT_VIEW REWRITE ACCESS FULL| MVW  |     2 |    60 |     3   (0)| 00:00:01 |                                                                                                                                                                                                                        
-------------------------------------------------------------------------------------    

但是任何其他查询仍将使用原始表:

explain plan for
SELECT * FROM tbl where flags LIKE '%current_step: working%';
select * from table(dbms_xplan.display);

--------------------------------------------------------------------------                                                                                                                                                                                                                                   
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |                                                                                                                                                                                                                                   
--------------------------------------------------------------------------                                                                                                                                                                                                                                   
|   0 | SELECT STATEMENT  |      |     1 |    27 |     3   (0)| 00:00:01 |                                                                                                                                                                                                                                   
|*  1 |  TABLE ACCESS FULL| TBL  |     1 |    27 |     3   (0)| 00:00:01 |                                                                                                                                                                                                                                   
--------------------------------------------------------------------------                                                                                                                                                                                                                                   

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

   1 - filter("FLAGS" LIKE '%current_step: success%' AND "FLAGS" IS NOT                                                                                                                                                                                                                                      
              NULL)              

当然,如果允许修改查询,虚拟索引会更简单......

答案 1 :(得分:0)

您可能正在寻找全文搜索索引。

有几种方法可以实现这个:

  • Oracle拥有Oracle Text,您可以在其中定义所需的全文索引类型。
  • Lucene是一个Java全文搜索框架。
  • Solr是一种提供全文搜索的服务器产品。

答案 2 :(得分:0)

  

我宁愿不添加布尔列来存储预先计算的值,因为这需要在应用程序中更改代码

我可以建议两种方式:

<强> 1

如果您使用的是11g及以上,当值为VIRTUAL COLUMN时,您可以将complete始终生成为1,然后您需要执行此操作:

select * from table where virtual_column = 1

为了提高效果,你可以有一个索引,相当于function-based index

<强> 2

更新:也许,我应该更清楚我的第二点:source

在某些情况下,Oracle会使用index来解析'%text%'模式的类似内容。如果可以在不必返回到表(rowid lookup)的情况下解析查询,则可以选择索引。示例:

select distinct first_nm from person where first_nm like '%EV%';

在上述情况下,Oracle会执行 index fast full scan - 对较小索引的完整扫描。