Hi,
I want to get a ResultSet and the query contains a lot of Parameters.
If I use an inline Query then it works but if I use a PreparedStatement with indexed Parameters there seems to be a problem.
Here is an example for this strange behaviour.
You can download the whole Example as maven project at http://jmlp.volans.uberspace.de/ftp/issueExample.zip
Note: For generating the sql I use jooq library. I also posted the issue at their repository but it seems that it is h2 specific. (https://github.com/jOOQ/jOOQ/issues/2768)--
@Test
public void testBugExample() throws SQLException {
/* Preparation of Data */
DSLContext dsl = DSL.using(this.con, SQLDialect.H2);
List<Long> activeFolders = dsl.select(FILES.ID).from(FILES).where(FILES.TYP.eq("D"), FILES.AVAILABLE.isTrue()).fetch(FILES.ID);
List<Long> activeFiles = dsl.select(FILES.ID).from(FILES).where(FILES.TYP.eq("F"), FILES.AVAILABLE.isTrue()).fetch(FILES.ID);
/* the Query with the Bug */
SelectConditionStep<Record1<Long>> qry = dsl.select(FILES.ID).from(FILES).join(FOLDERMAP).on(FILES.ID.eq(FOLDERMAP.ID))
.where(FILES.ID.notIn(activeFiles), FOLDERMAP.PARENT.in(activeFolders));
String qryIndexed = qry.getSQL(ParamType.INDEXED);
String qryInline = qry.getSQL(ParamType.INLINED);
/* InlineParameter work */
log.info("Query Inline: " + qryInline);
{
Statement stm = con.createStatement();
ResultSet rs = stm.executeQuery(qryInline);
while (rs.next())
rs.getLong(1);
rs.close();
stm.close();
}
/* InlineParameter work */
log.info("Query Indexed: " + qryIndexed);
{
PreparedStatement stm = con.prepareStatement(qryIndexed);
/* set Parameter */
int pos = 1;
for (Long e : activeFiles)
stm.setLong(pos++, e);
for (Long e : activeFolders)
stm.setLong(pos++, e);
ResultSet rs = stm.executeQuery();
while (rs.next())
rs.getLong(1);
rs.close();
stm.close();
}
/* does not finish to this line */
log.info("finish");
}
You received this message because you are subscribed to the Google Groups "H2 Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email to h2-database...@googlegroups.com.
To post to this group, send email to h2-da...@googlegroups.com.
Visit this group at http://groups.google.com/group/h2-database.
For more options, visit https://groups.google.com/groups/opt_out.
"main" prio=6 tid=0x0000000001d2e000 nid=0x1798 runnable [0x0000000001d0d000]
java.lang.Thread.State: RUNNABLE
at org.h2.value.Value.convertTo(Value.java:507)
at org.h2.expression.Function.getSimpleValue(Function.java:781)
at org.h2.expression.Function.getValueWithArgs(Function.java:992)
at org.h2.expression.Function.getValue(Function.java:466)
at org.h2.expression.ConditionIn.getValue(ConditionIn.java:52)
at org.h2.expression.ConditionNot.getValue(ConditionNot.java:33)
at org.h2.expression.ConditionAndOr.getValue(ConditionAndOr.java:94)
at org.h2.expression.ConditionAndOr.getValue(ConditionAndOr.java:94)
at org.h2.expression.Expression.getBooleanValue(Expression.java:180)
at org.h2.command.dml.Select.queryFlat(Select.java:520)Hi
Thanks for the updated test case.
I've looked into this, and the situation is thusly:
We have special case optimised code for handling "IN (1,2,3)" queries.
Unfortunately, for "IN (?,?,?)" queries the optimised code does not get used because we at the point in time we run the optimiser, the optimiser sees the prepared-statement-parameters and bails out.
Running the optimiser on a PreparedStatement kind of defeats the point of a PreparedStatement, which is to minimise per-execution setup cost.
It might be possible to teach the code in org.h2.expression.ConditionIn#optimize to handle this case, but I'm loathe to add that much complexity for corner cases like this.
I'll think about it some more.
Hi,
Would it be possible to disable generating CAST? If the bind variable is set using PreparedStatement.setLong, I don't see why CAST would be needed.
Of course support for superfluous CAST (or any deterministic function on a parameter) could be implemented in H2, but so far it wasn't needed, and I'm hesitant to implement features that are not really needed. Also, it might break a known workaround to force not using a certain index (using the expression "-ID=-?"). I know that's a hack :-)
> I don't think it's slow because of a missing index.
OK, so the index is not be missing, but it is probably not used because of the CAST function. That would explain the difference.
In general, I would probably use a profiler to check what's going on. See also http://h2database.com/html/performance.html#built_in_profiler - also, it would help to know the query plans, see http://h2database.com/html/performance.html#explain_plan
Regards,
Thomas
--
You received this message because you are subscribed to a topic in the Google Groups "H2 Database" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/h2-database/1B4PuijeaYU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to h2-database...@googlegroups.com.
--
You received this message because you are subscribed to the Google Groups "H2 Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email to h2-database...@googlegroups.com.
You received this message because you are subscribed to the Google Groups "H2 Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email to h2-database...@googlegroups.com.