Индекс первичного ключа не используется - PullRequest
0 голосов
/ 20 марта 2019

Я использую Oracle 12C, и у меня есть следующий код

SELECT
        d.id,
        'Status' "ImportStatus",
        p.importid "ImportID",
        macid,
        p.daterequire "CreateDate",
        p.dateimport "DateImPort",
        TRANSLATE(p.accrequire USING NCHAR_CS) "CreateBy",
        TRANSLATE(p.accimport USING NCHAR_CS) "AccImPort",
        0 "isEdit",
        employee,
        deptid partner,
        equipmentid
    FROM
        (
            SELECT 
                id,
                importid,
                daterequire,
                dateimport,
                accrequire,
                accimport,
                subdeptid employee,
                deptid
            FROM
                tableA
            WHERE
                estatus = 2
                AND createdate BETWEEN to_timestamp('01/01/2019','dd/mm/yyyy') AND to_timestamp('12/02/2019','dd/mm/yyyy')
        ) p
        INNER JOIN tableB d ON d.importid = p.id

В TableA было 5 м значений, а в TableB 3 м.

Importid - это уникальный столбец с типом данных varchar2.Идентификатор - это PK с типом данных.

Вот план выполнения:

https://i.stack.imgur.com/tR2Q9.png

Как видно, в PK нет индекса, и это приводит к высокой стоимости.Есть ли способ помочь мне решить эту проблему?

Спасибо!

1 Ответ

0 голосов
/ 21 марта 2019

Прежде всего, вы должны учитывать, что индексы не всегда являются хорошей идеей .

Если Oracle будет читать большинство данных из таблицы, это будетиспользуйте FULL TABLE SCAN, поскольку это быстрее, чем сначала чтение блоков индекса, а затем чтение блоков данных.Слишком много операций ввода-вывода.

Теперь вернемся к вашему вопросу.
Вы можете заставить Oracle использовать индекс, если хотите, предоставив подсказку:

/*+ INDEX(table_name index_name) */

Вы можете добавить его в свой запрос и проверить, что происходит с планом запроса и скольконовый план будет стоить:

SELECT  /*+ INDEX(tableA index_name) */     --replace 'index_name' with the name of your index
        d.id,
        'Status' "ImportStatus",
        p.importid "ImportID",
        macid,
        p.daterequire "CreateDate",
        p.dateimport "DateImPort",
        TRANSLATE(p.accrequire USING NCHAR_CS) "CreateBy",
        TRANSLATE(p.accimport USING NCHAR_CS) "AccImPort",
        0 "isEdit",
        employee,
        deptid partner,
        equipmentid
    FROM
        (
            SELECT 
                id,
                importid,
                daterequire,
                dateimport,
                accrequire,
                accimport,
                subdeptid employee,
                deptid
            FROM
                tableA
            WHERE
                estatus = 2
                AND createdate BETWEEN to_timestamp('01/01/2019','dd/mm/yyyy') AND to_timestamp('12/02/2019','dd/mm/yyyy')
        ) p
        INNER JOIN tableB d ON d.importid = p.id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...