Как я могу использовать этот вид индекса? - PullRequest
0 голосов
/ 01 мая 2019

Я пытаюсь использовать тип индекса и не работает. Может быть, вы можете помочь мне понять, что я делаю неправильно.

Это определение моей таблицы:

CREATE TABLE "TIR"."INT07NCMP"(
    "INT07_CORRELATIVO" NUMBER(10) NOT NULL ENABLE,
    "INT07_CENTRO" VARCHAR2(4 BYTE) NOT NULL ENABLE, 
    "INT07_CODCOMPONENTE" VARCHAR2(18 BYTE) NOT NULL ENABLE, 
    "INT07_ALMCOMPONENTE" VARCHAR2(4 BYTE) NOT NULL ENABLE, 
    "INT07_CANCOMPONENTE" NUMBER(13,3), 
    "INT07_UNICOMPONENTE" VARCHAR2(3 BYTE), 
    "INT07_CODPORTADOR" VARCHAR2(18 BYTE) NOT NULL ENABLE, 
    "INT07_ALMPORTADOR" VARCHAR2(4 BYTE) NOT NULL ENABLE, 
    "INT07_CANPORTADOR" NUMBER(13,3), 
    "INT07_UNIPORTADOR" VARCHAR2(3 BYTE), 
    "INT07_ALMDESTINO" VARCHAR2(4 BYTE) NOT NULL ENABLE, 
    "INT07_FECINICIO" VARCHAR2(10 BYTE) NOT NULL ENABLE, 
    "INT07_HORINICIO" VARCHAR2(8 BYTE) NOT NULL ENABLE,
    "INT07_FECTERMINO" VARCHAR2(10 BYTE) NOT NULL ENABLE, 
    "INT07_HORTERMINO" VARCHAR2(8 BYTE) NOT NULL ENABLE,
    "INT07_ESTPOCH" VARCHAR2(1 BYTE), 
    "INT07_TMPPOCH" TIMESTAMP (6), 
    "INT07_ESTSAP" VARCHAR2(1 BYTE), 
    "INT07_TMPSAP" TIMESTAMP (6), 
    "INT07_TIMESTAMP" TIMESTAMP (6) NOT NULL ENABLE, 
    CONSTRAINT "INT07NCMP_PK" PRIMARY KEY ("INT07_CORRELATIVO"),
    CONSTRAINT "INT07NCMP_UK1" UNIQUE (
        "INT07_CENTRO", "INT07_CODCOMPONENTE", "INT07_ALMCOMPONENTE", "INT07_CODPORTADOR", "INT07_ALMPORTADOR",
        "INT07_FECINICIO", "INT07_HORINICIO", "INT07_FECTERMINO", "INT07_HORTERMINO"
    )
);

и вот индексы, которые я создал:

CREATE INDEX "TIR"."INT07NCMP_IDX1" ON "TIR"."INT07NCMP" ("INT07_CENTRO", "INT07_ESTPOCH");
CREATE INDEX "TIR"."INT07NCMP_IDX2" ON "TIR"."INT07NCMP" ("INT07_CENTRO", "INT07_ESTSAP");
CREATE INDEX "TIR"."INT07NCMP_IDX3" ON "TIR"."INT07NCMP" ("INT07_CENTRO", "INT07_CORRELATIVO", "INT07_FECINICIO", "INT07_HORINICIO", "INT07_FECTERMINO", "INT07_HORTERMINO");

Используя "Объяснить план", я хорошо справляюсь с индексами 1 и 2, но нет с индексом 3. Например, я пытаюсь выполнить этот запрос:

SELECT * FROM INT07NCMP
WHERE INT07_CENTRO = '7100'
AND INT07_CORRELATIVO > 0

и это ответ:

Plan hash value: 2810525850

----------------------------------------------------------------------------------------------
| Id  | Operation                   | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                |  9770 |  1450K|     1   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS BY INDEX ROWID| INT07NCMP      |  9770 |  1450K|     1   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | INT07NCMP_IDX1 |    39 |       |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("INT07_CORRELATIVO">0)
   2 - access("INT07_CENTRO"='7100')

Note
-----
   - dynamic sampling used for this statement (level=2)

Итак, как вы можете видеть, использовался только IDX1, и я ожидал использовать IDX3, потому что я фильтрую с помощью «INT07_CENTRO», а затем «INT07_CORRELATIVO», как порядок определения индекса. Если я попытаюсь установить больше фильтров (все столбцы IDX3), это тоже не сработает.

Любой намек на это?

Спасибо

1 Ответ

2 голосов
/ 01 мая 2019

Предполагая, что у вас хорошая статистика. num_rows в user_tables и user_indexes.

Допустим, лучший подход в этих случаях - просто поверить, что БД принимает правильное решение. он рассматривает много аспектов, например, stats физической организации и т. д. Так что делайте индексы так, как они должны, и создавайте запросы в соответствии с правилами данных, а затем доверяйте БД.

В очень редких случаях вам может потребоваться форсировать запрос. Вы можете использовать подсказки. Но в этом случае, если это не сильно отличается, в чем я сомневаюсь - просто добавление корреляции в конце первого индекса будет хорошо. Потому что сохранение будет происходить не от сканирования диапазона на этом, а тому оракулу не нужно было идти к таблице базы данных, чтобы получить это, и сканирования индекса было достаточно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...