【问题标题】:How to index the attributes of the associated table in Oracle?Oracle中如何对关联表的属性进行索引?
【发布时间】:2020-07-04 06:02:16
【问题描述】:

为了优化以下语句的查询添加索引:

SELECT SUPPLIER.COMPANY_NAME, SUPPLIER.CITY
FROM PRODUCT JOIN SUPPLIER
ON PRODUCT.SUPPLIER_NAME = SUPPLIER.COMPANY_NAME;

我写的声明如下:

EXPLAIN PLAN FOR SELECT PRODUCT.SUPPLIER_NAME, SUPPLIER.COMPANY_NAME FROM PRODUCT,SUPPLIER;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
CREATE INDEX PS_IDX_SC ON PRODUCT,SUPPLIER(PRODUCT.) ;
EXPLAIN PLAN FOR SELECT PRODUCT.SUPPLIER_NAME, SUPPLIER.COMPANY_NAME FROM PRODUCT JOIN SUPPLIER;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
DROP INDEX PS_IDX_SC;

第45行的语句怎么写,谢谢。

【问题讨论】:

    标签: sql oracle oracle-sqldeveloper datagrip


    【解决方案1】:

    您不能在两个表上创建索引。

    您需要创建两个单独的索引,如下所示:

    CREATE INDEX PS_IDX_PS ON PRODUCT(SUPPLIER_NAME) ; 
    
    CREATE INDEX PS_IDX_SC ON SUPPLIER(COMPANY_NAME) ; 
    

    【讨论】:

    • 谢谢你,我正在学习 Oracle,我遇到了很多问题。
    • 试一试,如果它适用,那么您应该接受答案,以便您的问题被标记为已解决。
    【解决方案2】:

    让我尝试以不同的方式回答您的问题,尝试简要概述索引的用途,有时它们不是答案。您正在根据条件连接两个表,但没有过滤。当您需要分析性能问题,并且您认为索引就是答案时,请尝试多考虑一下。

    在您的特定情况下,联接没有过滤器,因此您显示供应商名称和公司名称。但是您的查询仅显示两列:产品表中的供应商名称和供应商表中的公司名称。但是,这里的加入条件是什么?我猜company_name 和supplier_name 是相同的,但是如果你问我,从两个表中检索相同的列没有任何意义。

    原始查询

    SQL> SELECT PRODUCT.SUPPLIER_NAME, SUPPLIER.COMPANY_NAME FROM PRODUCT JOIN SUPPLIER;
    

    重写查询

    SQL> SELECT PRODUCT.SUPPLIER_NAME, SUPPLIER.COMPANY_NAME FROM PRODUCT JOIN SUPPLIER 
         on PRODUCT.SUPPLIER_NAME = SUPPLIER.COMPANY_NAME;
    

    尝试始终编写连接条件,使查询更具可读性。在您的情况下,您可以在两个表中创建两个索引,正如@Tejash 之前向您展示的那样,但让我再解释一下其他内容。

    • 如果您的 SQL 查询只检索索引中存在的列,Oracle 可能会使用索引来访问数据。在这种情况下,按索引访问会比按表更快,因为索引比表小。
    • 但是,如果您的 SQL 查询检索到的列多于索引中包含的列(例如,product_name),那么在没有过滤器的情况下,看看索引是否使查询更快会非常有趣。在这种情况下,Oracle 可能会使用一种称为 TABLE ACCESS BY INDEX ROWID 的方法。这意味着Oracle访问索引以检索rowid,然后使用从索引中检索到的rowid去表中获取数据。在这种情况下,当涉及到更多列时,如果表足够大,我敢打赌通过表全扫描访问比通过索引访问更快。

    我的建议:使用 DBMS_STATS 获取两个表的统计信息。而且,如果您有 Oracle 11g 或更高版本,您很可能会这样做,您可能希望在添加索引而不影响您的环境时使用 Invisible Indexes 来验证这些查询的性能,然后当您确定,您可以让它们可见。

    SQL> CREATE INDEX IDX_PRO_SUP ON PRODUCT(SUPPLIER_NAME) INVISIBLE;
    
    SQL> CREATE INDEX IDX_SUP_COM SUPPLIER(COMPANY_NAME) INVISIBLE; 
    

    在您自己的会话中查看索引将如何与您的解释计划一起使用。

    SQL> ALTER SESSION SET OPTIMIZER_USE_INVISIBLE_INDEXES=TRUE;
    SQL> EXPLAIN PLAN FOR SELECT PRODUCT.SUPPLIER_NAME, SUPPLIER.COMPANY_NAME FROM 
         PRODUCT,SUPPLIER;
    SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
    

    然后,当您确定这些索引按预期工作时:

    SQL> ALTER INDEX IDX_PRO_SUP VISIBLE;
    
    SQL> ALTER INDEX IDX_SUP_COM VISIBLE;
    

    希望对您有所帮助。 最好的问候

    【讨论】:

    • 谢谢你,我需要花一些时间更好地理解你的答案,然后我会问你更多问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 1970-01-01
    • 2011-01-07
    • 2022-11-26
    • 1970-01-01
    • 2014-09-26
    • 2013-01-21
    相关资源
    最近更新 更多