Тонкий клиент Oracle JDB - уникальный индекс с varchar2 не используется - PullRequest
1 голос
/ 18 ноября 2011

Первые основы сома.

Java 6 OJDBC6 Oracle 10.2.0.4 (также тот же результат в версии 11g)

Я чувствую, что SQL-оператор ведет себя по-разному при выполнении из Java с клиентом OJDBC6 и использованием инструмента SQL Gate, который, вероятно, использует собственный драйвер / 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 Query 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 трактуется по-разному.

1 Ответ

2 голосов
/ 20 ноября 2011

Я нашел ответ, и это было проще, чем я думал.Все это связано с типом данных VARCHAR2 столбца индекса.Моя база данных была установлена ​​на язык и страну "en", "US", но локально у меня есть другой язык и регион.Поэтому оптимизатор правильно отбросил индекс, поскольку он не был настроен на тот же язык и страну, что и клиент.

Итак, чтобы проверить это, я запустил затмение с некоторыми дополнительными параметрами -D, введенными в мой файл eclipse.ini.

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

Затем в проводнике источников данных в Eclipse я создал соединение и выполнил свое утверждение, и оно работало как чудо.

Итак, извлеченный урок - всегда следить за тем, чтобы клиент и база данных были совместимы с языком.Вероятно, мы изменимся, поэтому мы используем UTF-8 в базе данных, чтобы он был одинаковым для каждой установки.В противном случае вам придется настроить его для каждой установки в зависимости от страны и языка.

Надеюсь, это кому-нибудь поможет.Если ответ был неясен, пожалуйста, оставьте комментарий.

...