Oracle JDB瘦客户机 - 未使用varchar2的唯一索引

问题描述:

首先是som基础知识。Oracle JDB瘦客户机 - 未使用varchar2的唯一索引

的Java 6 OJDBC6 甲骨文10.2.0.4(也是同样的结果在11g版本)

我遇到与OJDBC6客户端从Java执行时一个SQL语句是不同的行为和使用工具SQL门可能使用本机/ OCI驱动程序。由于某些原因,优化器选择在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的处理方式不同。

+0

@jdssthlm - 当查询不引用该表时,为什么查询计划似乎显示查询触及'XXX_CUSTOMER'表(并且/或者该表上似乎是索引)?您确定您发布的查询与您发布的计划相符吗?您的Java代码是否在某处使用绑定变量来选择特定的键值?你确定Java代码在绑定时传递正确的数据类型吗? –

+0

你在Java中使用PreparedStatement吗? –

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

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

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

然后在Eclipse的数据源资源管理器中,我创建了一个连接并运行了我的语句,它的工作方式就像一个魅力。

因此,吸取的教训是始终看到客户端和数据库在语言上是兼容的。可能我们会改变,所以我们在数据库中使用UTF-8,所以每次安装都是一样的。否则,您将不得不根据国家和语言对每个安装进行配置。

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