2015-02-05 71 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