让我尝试以不同的方式回答您的问题,尝试简要概述索引的用途,有时它们不是答案。您正在根据条件连接两个表,但没有过滤。当您需要分析性能问题,并且您认为索引就是答案时,请尝试多考虑一下。
在您的特定情况下,联接没有过滤器,因此您显示供应商名称和公司名称。但是您的查询仅显示两列:产品表中的供应商名称和供应商表中的公司名称。但是,这里的加入条件是什么?我猜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;
希望对您有所帮助。
最好的问候