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的处理方式不同。
答
我找到了答案,比我想象的要简单。这一切都与索引列的VARCHAR2数据类型有关。我的数据库被设置为语言和国家“EN”,“美国”,但本地 我有另一种语言和地区。因此,由于优化器未配置与客户端相同的语言和国家,因此正确地放弃了该索引。
所以我做了测试它是在我的eclipse.ini文件中输入一些额外的-D参数来启动我的eclipse。
-Duser.language=en
-Duser.country=US
-Duser.region=US
然后在Eclipse的数据源资源管理器中,我创建了一个连接并运行了我的语句,它的工作方式就像一个魅力。
因此,吸取的教训是始终看到客户端和数据库在语言上是兼容的。可能我们会改变,所以我们在数据库中使用UTF-8,所以每次安装都是一样的。否则,您将不得不根据国家和语言对每个安装进行配置。
希望这会帮助别人。如果答案不清楚,请发表评论。
@jdssthlm - 当查询不引用该表时,为什么查询计划似乎显示查询触及'XXX_CUSTOMER'表(并且/或者该表上似乎是索引)?您确定您发布的查询与您发布的计划相符吗?您的Java代码是否在某处使用绑定变量来选择特定的键值?你确定Java代码在绑定时传递正确的数据类型吗? –
你在Java中使用PreparedStatement吗? –