JDBC在查询中对多个JOIN的响应缓慢

时间:2014-02-13 12:11:50

标签: java sql join jdbc db2

我在DB2数据库中有3个不同的表(没有任何主键或外键)

CREATE TABLE XW (
    SRCLB VARCHAR(10) NOT NULL,
    SRCFL VARCHAR(10) NOT NULL,
    SRCMB VARCHAR(10) NOT NULL,
    NAME VARCHAR(30) NOT NULL,
    VARSQ DOUBLE NOT NULL,
    UNIQUE (SRCLB, SRCFL, SRCMB, NAME, VARSQ) 
);

CREATE TABLE XO (
    LOBJ VARCHAR(10) NOT NULL,
    LTYPE VARCHAR(10) NOT NULL,
    ATTR VARCHAR(10) NOT NULL,
    LTEXT VARCHAR(50),
    UNIQUE (LOBJ, LTYPE, ATTR) 
);

CREATE TABLE XM (
    LIB VARCHAR(10) NOT NULL,
    FILE VARCHAR(10) NOT NULL,
    MBR VARCHAR(10) NOT NULL,
    SEQ DOUBLE NOT NULL,
    DTA VARCHAR(132),
    RECN INTEGER,
    UNIQUE (LIB, FILE, MBR, SEQ)
);

每个表都有2个lacs(appx)记录。当我执行此查询时

SELECT
        DISTINCT XW.SRCMB
        ,XM.SEQ
        ,XM.DTA
        ,XM. FILE
        ,XM.LIB
        ,XO.TEXT
        ,XO.ATTR
    FROM
        (
            XW INNER JOIN XM
                ON (XW.VRECN = XM.RECN)
                AND (XW.SRCMB = XM.MBR)
                AND (
                    XW.SRCFL = XM. FILE
                )
                AND (XW.SRCLB = XM.LIB)
        )
    LEFT OUTER JOIN XO
        ON (XW.SRCMB = XO.LOBJ)
WHERE
(XW.NAME = 'DB-NAME-A')
ORDER BY
XW.SRCMB
,XM.SEQ;

它会在15秒内返回结果。但是当我在WHERE条件中指定更多列时,如

SELECT
        DISTINCT XW.SRCMB
        ,XM.SEQ
        ,XM.DTA
        ,XM. FILE
        ,XM.LIB
        ,XO.TEXT
        ,XO.ATTR
    FROM
        (
            XW INNER JOIN XM
                ON (XW.VRECN = XM.RECN)
                AND (XW.SRCMB = XM.MBR)
                AND (
                    XW.SRCFL = XM. FILE
                )
                AND (XW.SRCLB = XM.LIB)
        )
    LEFT OUTER JOIN XO
        ON (XW.SRCMB = XO.LOBJ)
WHERE
(XW.NAME = 'DB-NAME-A')
AND XW.SRCMB = 'CLCR0751'
AND XW.SRCFL = 'CBSRC'
AND XW.SRCLB = 'THPCOD_NEW'
ORDER BY
XW.SRCMB
,XM.SEQ;

然后结果很快就会出现,例如2秒。 您能否告诉我表格/查询中的缺陷是什么?

如何改善第一次查询的效果?

在这种情况下,使用存储过程代替SQL查询是否有优势???

提前致谢

基肖尔

2 个答案:

答案 0 :(得分:4)

您在XW表上有一个索引。它由unique子句定义。这些是索引中的列:SRCLBSRCFLSRCMBNAME,然后是VARSQ

where子句中,索引必须从左到右使用 - 列的顺序有所不同。因此,当您在name上有条件时,无法使用索引。

如果您在SRCLBSRCFLSRCMBSRNAME上有条件,则可以使用该索引。

此外,过滤后where子句选择的数据量可能会更小,where子句中的更多相等条件,这也会提高性能。

答案 1 :(得分:2)

听起来这只是一个规模问题。

WHERE子句切掉每个组的片段。优化器首先执行这些操作,因此当它在JOIN上启动时,只需要做的工作就少了。它应该是返回的总行数的函数。

你需要做一些事情:

  1. 运行与EXPLAIN PLAN等效的DB2,以查看TABLE SCAN是否正在完成。如果是,也许你需要更多的索引
  2. 创建一个视图并查询该视图。摊还JOIN时间。
  3. 问问自己你真正需要什么样的记录。