我在 Spring Web 服务中使用 mybatis 查询来验证用户的输入,以便在继续执行任何其他工作之前检查 Oracle 数据库中是否存在给定的 key 。目的是使此验证快速运行,并在不同表/列的多种 Web 方法中重用。
我向查询传递一个 HashMap,其中包含表 (tableType)、列 (selectColumnType) 和键 (id) 的标识符我想检查一下。我的设计是查询只返回 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 万行的表,在 Toad 中运行此查询大约需要 20 秒,而在 Web 服务上下文中则需要 45 秒以上。这些键预计不会是唯一的,因此我认为使用 FETCH FIRST 1 ROW ONLY
或 ROWNUM = 1
是可行的方法,但性能仍然不存在.
我希望有一种更有效的方法,可以使用 Oracle 功能或 mybatis 来仅检索第一个匹配项并返回。
最佳答案
我对你设置的任何标签一无所知,除了一点点Oracle;因此,如果没有多大帮助,我们深表歉意。
您是否在 WHERE 子句中引用的列上创建了索引?如果没有,那就去做吧。
除此之外,为什么在这里使用正则表达式?尽管它看起来智能并且使您能够做一些很棒的事情,但在具有 2700 万行的表上它可能会非常慢。如果可能,将其转换为 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”意味着“是的,我发现了一些东西”):
select 1 from some_table where instr(some_column, id) > 0 and rownum = 1
抱歉,但我不知道如何使用您使用的语法重写该代码,因为我不熟悉它,但我希望您能做到。
关于sql - 在 Oracle 数据库中查找键是否存在的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49576465/