2015-02-05 36 views
2

我需要使用“IN”谓词进行查询,但是,jOOQ将我的“IN”呈现为“EXISTS”+ 2x嵌套选择。 但是,在DB2上,“IN”更快(500ms vs 8s)。我如何强制jOOQ以与我通过DSL API描述相同的方式呈现我的“IN”谓词?jOOQ - 呈现IN而不是EXIST

示例代码:

try (Connection connection = DriverManager.getConnection("jdbc:h2:mem:")) { 
    Settings settings = new Settings().withRenderFormatted(true); 
    DSLContext ctx = DSL.using(connection, SQLDialect.SQL99, settings); 
    ctx 
    .createTable("FOOBAR") 
    .column("FOO", SQLDataType.INTEGER) 
    .column("BAR", SQLDataType.INTEGER) 
    .execute(); 
    String sql = ctx 
    .select() 
    .from(DSL.tableByName("FOOBAR")) 
    .where(
     DSL.row(DSL.fieldByName("FOO")).in(ctx 
      .select(DSL.fieldByName("BAR")) 
      .from(DSL.tableByName("FOOBAR")) 
     ) 
    ) 
    .getSQL(); 
    System.out.println(sql); 
} 

结果:

select * 
from "FOOBAR" 
where exists (
    select "alias_2"."alias_2_0" 
    from (
    select "BAR" 
    from "FOOBAR" 
) "alias_2"("alias_2_0") 
    where ("FOO") = ("alias_2"."alias_2_0") 
) 
+0

您为什么不使用DB2方言? – 2015-02-06 13:54:09

+0

为什么不包含在免费版本中? ;) – LoganMzz 2015-02-06 14:08:28

+2

因为我们的汗水和眼泪使得DB2集成工作必须得到回报! – 2015-02-06 16:19:44

回答

2

SQLDialect.SQL99方言不理智命名。它暗示它会生成应该在任何数据库上运行的SQL,但这是不正确的。它只会生成“默认”的SQL。这将在JOOQ 3.6中得到纠正:#3844

为了优化用于DB2数据库的SQL生成,您应该改用SQLDialect.DB2方言。您在这里遇到的问题不会是唯一的问题...

+0

默认和SQL-99的声音与我相似(至少在这种情况下)。当我使用“IN”时,我期望“IN”被渲染为默认值(或SQL标准)。 这是一个想要的限制,以便为您的出色工作“获得回报”(并且没有什么会改变),或者是由于“商业代码清理”(它将被修复)而导致的意外行为? – LoganMzz 2015-02-06 17:29:08

+0

@mlogan:你永远不应该期待“SQL99”或“DEFAULT”方言的任何有意义的输出。它也可以被称为“UNKNOWN”或“DONTCARE”......我同意在这种情况下,应该可以呈现“IN”,但是如果“DEFAULT”不应该依赖于渲染,那是因为只是在调试时(以及没有具体的方言可用时)用于'toString()'实现。 – 2015-02-06 22:43:16