在 Oracle 数据库中查找键是否存在的最快方法

Fastest way to find existence of key in Oracle database

我在我的 Spring Web 服务中使用 mybatis 查询来验证用户的输入,只要在继续执行任何其他工作之前检查给定的键是否存在于 Oracle 数据库中。目的是此验证 运行 可以快速完成,并在不同 tables/columns 的多个 Web 方法中重复使用。

我向查询传递了一个 HashMap,其中包含 table (tableType)、列 (selectColumnType) 和我要检查的密钥 (id)。我的设计是查询 return 只有一个 0 或 1,表示该键是否存在。

<select id="checkExistence" parameterType="java.util.HashMap"
    resultType="int">
    SELECT COUNT (*) FROM ( SELECT CAST(${ selectColumnType } AS 
    VARCHAR2(1000)) FROM ${ tableType } WHERE REGEXP_LIKE (${
    selectColumnType }, #{ id }) FETCH FIRST 1 ROW ONLY)
</select>

不幸的是,在某些情况下,这个查询的性能是不能容忍的。从具有大约 2700 万行的 table 到 运行 Toad 中的此查询大约需要 20 秒,而在 Web 服务的上下文中则需要 45 秒以上。密钥预计不会是唯一的,所以我认为使用 FETCH FIRST 1 ROW ONLYROWNUM = 1 是可行的方法,但性能仍然不存在。

我希望有一种更有效的方法,使用 Oracle 功能或 mybatis 只检索第一个匹配项和 return。

我对你设置的任何标签一无所知,除了一点Oracle;因此,如果帮不上什么忙,请见谅。

您是否在 WHERE 子句中引用的列上创建了索引?如果没有,那就去做吧。

除此之外,你为什么在这里使用正则表达式?虽然它看起来 聪明 并且可以让你做一些很棒的事情,但在具有 2700 万行的 table 上它可能会非常慢。如果可能,将其转换为 INSTR。例如:

No : select * from some_table where regexp_like(some_column, id)
Yes: select * From some_table where instr(some_column, id) > 0

此外,如果您使用 ROWNUM 限制结果,可能会有一些改进(结果为“1”,表示 "yes, I found something"):

select 1 from some_table where instr(some_column, id) > 0 and rownum = 1

抱歉,我不熟悉如何使用您使用的语法重写该代码,但我希望您能做到。