【发布时间】:2011-11-18 15:22:59
【问题描述】:
第一个 som 基础知识。
Java 6 OJDBC6 Oracle 10.2.0.4(11g版本也一样)
当使用 OJDBC6 客户端从 Java 执行并使用可能使用本机/OCI 驱动程序的工具 SQL Gate 时,我发现一条 sql 语句的行为有所不同。出于某种原因,优化器选择对 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 的处理方式不同。
【问题讨论】:
-
@jdssthlm - 当查询不引用该表时,为什么查询计划显示查询命中
XXX_CUSTOMER表(和/或该表上的索引)?您确定您发布的查询与您发布的计划相匹配吗?您的 Java 代码是否在某处使用绑定变量来选择特定的键值?您确定 Java 代码在进行绑定时传递了正确的数据类型吗? -
你在 Java 中使用 PreparedStatement 吗?
标签: oracle indexing client jdb varchar2