我在我的Spring网络服务中使用mybatis查询来验证用户的输入,只要在继续执行任何其他工作之前检查Oracle数据库中是否存在给定密钥。目的是该验证快速运行,并在不同表/列的多个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更有效地检索第一个匹配并返回。
答案 0 :(得分:2)
除了一点点Oracle之外,我对你设置的任何标签都一无所知;因此,抱歉,如果它没有多大帮助。
您是否在WHERE子句中引用的列上创建了索引?如果没有,那就去做吧。
除此之外,你为什么要在这里使用正则表达式?虽然它看起来像是 smart 并且可以让你做出精彩的事情,但在拥有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限制结果,可能会有一些改进(&#34; 1&#34;,结果,意味着&#34;是的,我发现了一些&#34;):
select 1 from some_table where instr(some_column, id) > 0 and rownum = 1
很抱歉,但我不知道如何使用您不熟悉的语法重写代码,但我希望您能够管理。