如何为动态搜索字符串创建索引

时间:2010-01-23 19:27:54

标签: sql oracle plsql indexing

我有一个小DB,仅用于学术目的,我最多有对象表。 我在Power Designer中创建了一个实体关系模型(ERM),默认情况下,该程序为每个表的序列ID创建索引。

  1. 我想知道如何使用索引 就像在查询上那样。我愿意 想通过它的id找到一个产品, 但使用其索引。
  2. 是否可以select value(s) from supplierf where s.name LIKE '%search%' order by s.name 使用索引进行搜索 那?我知道有可能创造 名称的索引,但用于搜索 我不知道怎么回事 工作
  3. 让我说,我确实知道Oracle决定何时或是否值得在查询中使用索引,但我可能必须至少尝试在我的BD项目中使用索引

3 个答案:

答案 0 :(得分:6)

1。 通过将列定义为PRIMARY KEY(这是您的id列最有可能的列),Oracle会隐含地为此列创建索引。当您选择WHERE id=123时,它很可能会决定使用该索引。您可以在查询中提供hint以使Oracle使用索引(在大多数情况下),但这对您来说不是必需的。

2。 Oracle不太可能使用LIKE的索引(除非您知道文本以搜索到的字符串开头,并且您可以使用'xyz%')。有关何时以及如何使用索引进行全表扫描的详细信息,请参阅Tony Andrews' post

有关Oracle LIKE clause searches with text indexes的文章应提供有关处理全文搜索的方法的信息。

答案 1 :(得分:3)

关于你的观点1.):我不清楚你的意思:如果你明智地分配索引,你可以使用索引提示来强制索引使用,但让一个更好的想法让优化器首先执行它,然后,如果没有使用索引,请分析 为什么 (可能是特定情况下的索引使用不是最快的方式)。例如,如果您使用通配符匹配将ID搜索与搜索组合在一起,优化程序可能会决定,如果它必须是完整的表扫描(因为您的'%search%'术语),则表示没有使用您的id列上的索引添加了收益。

关于你的观点2.):如果你在搜索词的开头使用通配符匹配,那么(非常)不太可能使用索引。对于这样的搜索,请在此处查看Oracle全文语法:

http://www.oracle.com/technology/products/text/index.html

答案 2 :(得分:3)

  

是否有可能从supplierf执行选择值,其中s.name LIKE'%search%'按s.name顺序使用索引进行搜索?我知道可以为名称创建索引,但是对于像这样的搜索,我不知道它是如何工作的。

是的,但Oracle可能会选择不使用基于统计信息的索引。您可以通过提示告诉Oracle使用索引,但索引实际上是否有帮助将取决于您的数据。假设您有此表和索引:

create table t (id integer primary key, text varchar2(50), other_cols...);
create index t_i on t (text);

然后选择:

select * from t where text like '%something%';

有两种明显的方法可以回答这个问题:

  1. T
  2. 上的全表扫描
  3. 对T_I进行全索引扫描,然后在T_I中找到每个结果的1次ROWID查找。
  4. 假设T有100,000行,并且只有5行符合您的搜索条件。假设表T占用5000个块,索引T_I占1000(即只有T的大小的20%)。

    根据读取的查询的实际成本是:

    1. 5000读(T)
    2. 1000读数(T_I),然后通过ROWID = 1005读数读取3次T
    3. 显然,在这种情况下,指数更好。但是,Oracle倾向于假设LIKE查询将返回5%的行(即5000行),因此其估计成本(读取时间)将为:

      1. 5000读(T)
      2. 1000个读数(T_I),然后通过ROWID = 6000读数读取T的5000个读数
      3. 因此,在此示例中,Oracle将进行全表扫描,尽管索引搜索会更快。您可以提示查询使用索引:

        select /*+ index(t t_i) */ from t where text like '%something%';
        

        但请注意,如果您确定查询在大多数时间内返回的行数少于5%,则效果会更好。