当我通过在外部设置参数来执行查询时,查询执行时间会大大降低。
StopWatch stopWatch = new StopWatch();
stopWatch.start();
Query nativeQuery = mEntityManager.createNativeQuery(
"select first 100 * from ALL$ACC allacc0_ where allacc0_.code like ? order by allacc0_.code asc");
nativeQuery.setParameter(1, "FIMA%");
List resultList = nativeQuery.getResultList();
stopWatch.stop();
System.out.println(stopWatch.prettyPrint() + " Total row count: " + resultList.size());
StopWatch”:运行时间(毫秒)= 30868 ,总行数:4
stopWatch = new StopWatch();
stopWatch.start();
Query nativeQuery1 = mEntityManager.createNativeQuery(
"select first 100 * from ALL$ACC allacc0_ where allacc0_.code like 'FIMA%' order by allacc0_.code asc");
List resultList1 = nativeQuery1.getResultList();
stopWatch.stop();
System.out.println(stopWatch.prettyPrint()+ " Total row count: " + resultList1.size());
StopWatch”:运行时间(毫秒)= 10 总行数:4
你知道为什么吗?
spring-data-jpa 2.1.3.RELEASE
jaybird.version 3.0.5
答案 0 :(得分:1)
问题在于,当使用绑定变量时,Firebird无法优化LIKE
,因为它不知道您将使用什么值,因此它必须假设最坏的情况并创建无法使用的计划字段的索引。
另一方面,当您使用仅以%
通配符结尾(并且在其他位置不包含通配符_
或%
的文字时),Firebird可以优化为使用索引。例如,当您使用allacc0_.code like 'FIMA%'
时,Firebird将像使用allacc0_.code starting with 'FIMA'
一样执行查询,而starting with
可以使用索引(如果有)。
如果您希望参数具有相同的行为,请重写查询以改为使用starting with
:
Query nativeQuery = mEntityManager.createNativeQuery("select first 100 * from ALL$ACC allacc0_ where allacc0_.code starting with ? order by allacc0_.code asc");
nativeQuery.setParameter(1, "FIMA");
《 {@ 3}}的Firebird语言参考》中也对此进行了记录:
关于
LIKE
和优化程序[..]
LIKE
谓词不使用索引。但是,如果 谓词采用LIKE 'string%'
的形式,它将转换为STARTING WITH
谓词,它将使用索引。因此-如果您需要搜索字符串的开头,则为 建议使用
STARTING WITH
谓词而不是LIKE
谓词。
答案 1 :(得分:0)