2011-11-18 55 views
1

首先是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嗎? –

回答

2

我找到了答案,比我想象的要簡單。這一切都與索引列的VARCHAR2數據類型有關。我的數據庫被設置爲語言和國家「EN」,「美國」,但本地 我有另一種語言和地區。因此,由於優化器未配置與客戶端相同的語言和國家,因此正確地放棄了該索引。

所以我做了測試它是在我的eclipse.ini文件中輸入一些額外的-D參數來啓動我的eclipse。

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

然後在Eclipse的數據源資源管理器中,我創建了一個連接並運行了我的語句,它的工作方式就像一個魅力。

因此,吸取的教訓是始終看到客戶端和數據庫在語言上是兼容的。可能我們會改變,所以我們在數據庫中使用UTF-8,所以每次安裝都是一樣的。否則,您將不得不根據國家和語言對每個安裝進行配置。

希望這會幫助別人。如果答案不清楚,請發表評論。