1

首先是一些基础知识。

Java 6 OJDBC6 Oracle 10.2.0.4(在 11g 版本中也是同样的结果)

我遇到一个 sql 语句在使用 OJDBC6 客户端从 Java 执行并使用可能使用本机/OCI 驱动程序的工具 SQL Gate 时表现不同。出于某种原因,优化器选择对 Java 中执行的语句使用散列连接,而不是其他语句。

这是表格:

CREATE TABLE DPOWNERA.XXX_CHIP (
   xxxCH_ID        NUMBER(22)       NOT NULL, 
   xxxCHP_ID       NUMBER(22)       NOT NULL, 
   xxxSP_ID        NUMBER(22)           NULL, 
   xxxCU_ID        NUMBER(22)           NULL, 
   xxxFT_ID        NUMBER(22)           NULL, 
   UEMTE_ID        NUMBER(38)           NULL, 
   xxxCH_CHIPID    VARCHAR2(30)     NOT NULL
)

指数:

ALTER TABLE DPOWNERA.XXX_CHIP ADD
  (
     CONSTRAINT IX_AK1_XXX_CHIPV2
     UNIQUE ( XXXCH_CHIPID )
     USING INDEX
     TABLESPACE DP_DATA01 
     PCTFREE 10
     INITRANS 2
     MAXTRANS 255
     STORAGE (
        INITIAL 128 K
        NEXT 128 K
        MINEXTENTS 1
        MAXEXTENTS UNLIMITED
    )
);

这是我使用的 SQL:

SELECT *
    FROM   (SELECT m2.*,
            rownum rnum
            FROM   (SELECT m_chip.xxxch_id,
                      m_chip.xxxch_chipid
                      FROM   xxx_chip m_chip
                      ORDER  BY m_chip.xxxch_chipid) m2
            WHERE  rownum < 101)
WHERE  rnum >= 1; 

最后是解释计划的摘录:

SQL 工具查询:

OPERATION        OBJECT_NAME         COST  CARDINALITY CPU_COST
---------------- ------------------- ----- ----------- ----------
SELECT STATEMENT NULL                    2          10      11740
VIEW             NULL                    2          10      11740
COUNT            NULL                 NULL        NULL       NULL
VIEW             NULL                    2          10      11740
NESTED LOOPS     NULL                    2          10      11740
TABLE ACCESS     XXX_CHIP                1     1000000       3319
INDEX            IX_AK1_XXX_CHIPV2       1          10       2336
TABLE ACCESS     XXX_CUSTOMER            1           1        842
INDEX            IX_PK_XXX_CUSTOMER      1           1        105

QQL Java 查询 OJDBC 瘦客户端:

**OPERATION        OBJECT_NAME         COST  CARDINALITY CPU_COST**
SELECT STATEMENT NULL                15100         100 1538329415
VIEW             NULL                15100         100 1538329415
COUNT            NULL                 NULL        NULL       NULL
VIEW             NULL                15100     1000000 1538329415
SORT             NULL                15100     1000000 1538329415
HASH JOIN        NULL                 1639     1000000  424719850
VIEW             index$_join$_004        3           3    2268646
HASH JOIN        NULL                 NULL        NULL       NULL
INDEX            IX_AK1_XXX_CUSTOMER     1           3        965
INDEX            IX_PK_XXX_CUSTOMER      1           3        965
TABLE ACCESS     xxx_CHIP             1614     1000000  320184788

所以,我不知道为什么优化器选择了哈希连接?我的猜测是 varchar2 的处理方式不同。

4

1 回答 1

2

我找到了答案,它比我想象的要简单。这一切都与索引列的 VARCHAR2 数据类型有关。我的数据库设置为语言和国家“en”、“US”,但在本地我有另一种语言和地区。因此优化器正确地丢弃了索引,因为它没有配置与客户端相同的语言和国家。

所以我测试它的方法是在我的 eclipse.ini 文件中输入一些额外的 -D 参数来启动我的 eclipse。

-Duser.language=en
-Duser.country=US
-Duser.region=US

然后在 Eclipse 的数据源浏览器中,我创建了一个连接并运行了我的语句,它就像一个魅力。

因此,经验教训是始终确保客户端和数据库在语言方面兼容。可能我们会改变,所以我们在数据库中使用 UTF-8,所以每次安装都一样。否则,您必须根据国家和语言为每次安装进行配置。

希望这会对某人有所帮助。如果答案不清楚,请发表评论。

于 2011-11-20T08:59:46.130 回答