喜欢使用领先的通配符Oracle

时间:2016-09-01 15:01:12

标签: sql oracle

我只有街道名称,我正在尝试搜索数据库中包含街道名称的所有地址。例如,我有Mojave Rd,数据库值可能是123 Mojave Rd Las Vegas。这迫使我使用前导和结束通配符。我正在尝试对数百个街道名称运行以下查询。执行计划看起来不错,但查询不断超时。我该如何优化

SELECT
  full_address,
  city,
  state,
  zip
FROM
  address_table
WHERE
  full_address LIKE '%MOJAVE RD%'
AND 
  state IN ('NV');

2 个答案:

答案 0 :(得分:1)

Oracle Text很适合。

超级基本示例:

CREATE INDEX test_idx_addr ON address_table (full_address)
indextype is ctxsys.context;

select * from address_table
where contains(full_address,'MOJAVE RD') > 0;

但它有很多,所以如果您决定使用它,请仔细阅读。

答案 1 :(得分:0)

我最喜欢Oracle Text解决方案。另一方面:

如果您在使用普通索引的简单解决方案之后,可以尝试覆盖索引并强制执行索引全扫描的计划。 这只是一个尝试而不打算成为所有案例的好解决方案的建议。

首先,我检查查询当前使用的计划。如果它使用全表扫描,这花费的时间太长,您可以尝试以下方法:

例如,将索引放在(state, full_address)上,然后检查查询的解释计划。如果它对新索引进行全面扫描,然后由Rowid进行表访问,那么它就完成了它的工作。

如果该计划没有自动获取索引(即它仍在执行FTS),您可以用这样的方式强制执行:

SELECT
  a.full_address,
  a.city,
  a.state,
  a.zip
FROM
  address_table a
WHERE a.rowid in (
  select a1.rowid from address_table a1
  where  a1.full_address LIKE '%MOJAVE RD%'
  AND   a1.state IN ('NV')
);

可能还有其他方法可以达到同样的效果。我们的想法是让它在索引上进行最快的扫描以匹配行,然后才能从表中获取所需的其余数据。

注意但是,此计划的效果可能会比当前情况更糟 - 特别是如果表中的匹配记录数量相当大

当然,如果您可以将要求更改为仅检索statefull_address列,则会更快(因为您可以避免完全访问该表)。