没有使用主键索引

时间:2019-03-20 10:49:21

标签: oracle primary-key oracle12c query-performance

我正在使用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的值为5m,TableB的值为3m。

Importid是具有varchar2数据类型的唯一列。 ID是具有数字数据类型的PK。

这是执行计划:

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

可以看出,PK中没有索引,这导致高成本。有什么办法可以帮助我解决问题?

谢谢!

1 个答案:

答案 0 :(得分:0)

首先,您应该考虑索引并不总是一个好主意

如果Oracle必须从表中读取最多的数据,它将使用FULL TABLE SCAN,因为它比先读取索引块然后再读取数据块快。涉及太多的IO操作。

现在,回到您的问题。
您可以通过提供提示来强迫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