为了优化以下语句的查询,请添加索引:
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行的声明,谢谢。
2条答案
按热度按时间jw5wzhpr1#
不能在两个表上创建索引。
您需要创建两个单独的索引,如下所示:
ne5o7dgx2#
让我试着用另一种方式来回答你的问题,试着给你一个关于索引是用来做什么的简短概述,有时它们不是答案。您正在根据一个条件连接两个表,但不进行筛选。当你需要分析一个性能问题,并且你认为一个索引就是答案时,试着多想想。
在您的特定情况下,join没有筛选器,因此显示供应商名称和公司名称。但是您的查询只显示两列:product表中的supplier\u name和supplier表中的company\u name。但是,这里的连接条件是什么?我猜公司名称和供应商名称是相同的,但是如果您要求的话,从两个表中检索相同的列没有任何意义。
原始查询
查询重写
尝试总是编写连接条件,使查询更具可读性。在您的例子中,您可以在这两个表中创建两个索引,正如@tejash之前向您展示的那样,但是让我再解释一些其他的内容。
如果sql查询只检索索引中存在的列,那么oracle可能会使用索引来访问数据。在这种情况下,按索引访问将比按表访问快,因为索引比表小。
但是,如果您的sql查询检索到的列比索引中包含的列(例如,产品名称)多,那么在没有筛选器的情况下,看看索引是否能使查询更快就非常有趣了。在这种情况下,oracle可能会使用一个名为table access by index rowid的方法。这意味着oracle访问索引以检索rowid,然后使用从索引检索到的rowid转到表以获取数据。在这种情况下,当涉及更多的列时,如果表足够大,我打赌通过表完整扫描进行访问要比通过索引进行访问快。
我的建议是:使用dbms\u stats获取这两个表的统计信息。而且,如果您有oracle11g或更高版本,您很可能会这样做,您可能希望在添加索引时使用不可见索引来验证这些查询的性能,而不影响您的环境,那么当您确定时,您可以使它们可见。
在自己的会话中查看索引如何与解释计划配合使用。
然后,当您确定这些索引按预期工作时:
希望有帮助。致以最诚挚的问候