Индекс для секционированной таблицы не используется - PullRequest
0 голосов
/ 12 января 2011

Мне нужно запросить достаточно большую таблицу (450M строк), которая разделена и проиндексирована.

Предположим, эта структура:

  • load_num (int)
  • cust_id (int)
  • ... еще несколько столбцов ...

Таблица разбита на load_num, примерно 3 загрузки идут в один раздел.(так что load_num не является уникальным в разделе)

Там есть три индекса, два из которых имеют load_num, cust_id в качестве первых двух столбцов (в том порядке)

Когда я выпускаю этоquery:

select *
from   fact
where  load_num = 100
       and cust_id = 12345

Возвращение занимает довольно много времени, поэтому я нажимаю план объяснения, и он получает правильный раздел, но затем выполняет полное сканирование таблицы на нем.

Почему oracle не использует один из двух индексов для сканирования ROWID в разделе, чтобы получить строки?

cust_id должен быть достаточно уникальным, а статистика в таблице увеличенана свидание.Мы находимся на 10g Entreprise.

Пришел из MS SQL, поэтому я пока не разбираюсь в Oracle.

Заранее спасибо,

Герт-Ян

** РЕДАКТИРОВАТЬ: Некоторые анимированные DDL:

CREATE TABLE FACT
(
  LOAD_NUM NUMBER 
... columns ..
, CUSTOMER_ID VARCHAR2(20 BYTE) 
.. columns 
) 
TABLESPACE "TS_A" 
PCTFREE 0 
INITRANS 1 
STORAGE 
( 
  BUFFER_POOL DEFAULT 
) 
PARALLEL 12 
PARTITION BY LIST (LOAD_NUM) 
(
  PARTITION FACT_46 VALUES (46) TABLESPACE FACT_PART_DATA_46 
    COMPRESS  
, PARTITION FACT_52 VALUES (52) TABLESPACE FACT_PART_DATA_52 
    COMPRESS  
, PARTITION FACT_56 VALUES (56) TABLESPACE FACT_PART_DATA_56 
    COMPRESS  
  ... more partitions ...
)CREATE INDEX SOMESCHEMA.FACT_IDX2 ON SOMESCHEMA.FACT (LOAD_NUM ASC, CUSTOMER_ID ASC, OUTSTANDING_ID ASC) 
LOCAL 
(
  PARTITION FACT_DATA_46 
  LOGGING 
  TABLESPACE "FACT_DATA_46" 
  PCTFREE 10 
  INITRANS 2 
  STORAGE 
  ( 
    INITIAL 65536 
    MINEXTENTS 1 
    MAXEXTENTS 2147483645 
    BUFFER_POOL DEFAULT 
  ) 
  NOCOMPRESS 
, PARTITION FACT_DATA_52
  LOGGING 
  TABLESPACE "FACT_DATA_52" 
  PCTFREE 10 
  INITRANS 2 
  STORAGE 
  ( 
    INITIAL 65536 
    MINEXTENTS 1 
    MAXEXTENTS 2147483645 
    BUFFER_POOL DEFAULT 
  ) 
  NOCOMPRESS 
, 
... etc etc ..
)

1 Ответ

3 голосов
/ 12 января 2011

Почему оракул не использует один из двух индексов для сканирования ROWID раздела, чтобы получить строки?

Трудно точно сказать, почему Oracle не делает 'не используйте индекс, поскольку в вашей настройке нет ничего, что могло бы помешать этому.

Скорее всего, распределение cust_id искажено, поэтому Oracle считает PARTITION SCAN более эффективным.

Не могли бы вы попробовать добавить подсказку в явном виде:

SELECT  /*+ INDEX (f FACT_IDX2) */
        *
FROM    fact f
WHERE   load_num = 100
        AND cust_id = 12345

Убедитесь, что он используется в плане, и убедитесь, что этот метод действительно быстрее.

Кроме того, пожалуйста, опубликуйте, что делает этот запросвозвращение:

SELECT  COUNT(*), COUNT(DECODE(cust_id, 12345, 1))
FROM    fact f
WHERE   load_num = 100
...