简体   繁体   English

Oracle-在连接表上执行视图创建索引

[英]Oracle- performing view- creating index on join table

I need to perform this view:我需要执行此视图:

  SELECT BMITEMCART, BMITEMXDSC, BMITEMCSTATO, 
  CASE 
  WHEN SCRECEXCONF = '2'  THEN 'CONFORME'
  WHEN SCRECEXCONF = '3'  THEN 'NON CONFORME'
  WHEN SCRECEXCONF = '4'  THEN 'PRESUNTO CONFORME'
  WHEN SCRECEXCONF = '5'  THEN 'NON APPLICABILE'
  ELSE '???????'
  END AS CERTIF
, BMITEMCTIPART
FROM PROD.BMITEM
LEFT OUTER JOIN PROD.SCRECE
             ON SCRECECCODART  = BMITEMCART AND
                SCRECENIDCERT  = 8          AND
                SCRECETFINE   IS NULL       AND
                SCRECEDFNVAL  IS NULL;

I read that creating indexes on the join tables would help.我读到在连接表上创建索引会有所帮助。 How should i create the index on the join table SCRECE?我应该如何在连接表 SCRECE 上创建索引? Should i create one index on the SCRECECCODART column, one on the SCRECENIDCERT column, one on the SCRECETFINE column and one on the SCRECEDFNVAL column, or what else?我应该在 SCRECECCODART 列上创建一个索引,在 SCRECENIDCERT 列上创建一个索引,在 SCRECETFINE 列上创建一个索引,在 SCRECEDFNVAL 列上创建一个索引,还是其他什么?

Thank you in advance.先感谢您。

You should take those general advice Index is good, Full Table Scan is bad!你应该接受那些一般性的建议Index 是好的,Full Table Scan 是坏的! with with some care.小心翼翼。

It always depends from the context of the usage.它总是取决于使用的上下文。

I reformulate your example removing the not relevant parts and using neutral column names我重新制定您的示例,删除不相关的部分并使用中性列名

I also added alias to qualify the columns, so it is clear from which table the columns are taken.我还添加了别名来限定列,因此可以清楚地从哪个表中获取列。

SELECT a.id, a.col1, a.col2, a.col3,
       b.col4
FROM a
LEFT OUTER JOIN b
             ON a.id  = b.fk_id AND
                b.col1 = 8 AND
                b.col2 IS NULL  AND
                b.col3 IS NULL 
            

Note, that in the join you selects all rows from the tables A - which means no index for access on table A will help .请注意,在连接中,您从表 A 中选择所有行- 这意味着对表 A 的访问没有索引会有所帮助 You have to full scan the table and process all rows.您必须全面扫描表并处理所有行。

You will see a HASH JOIN as a used join operation which is the prefered option if you join large datasets.您将看到HASH JOIN作为使用的连接操作,如果您连接大型数据集,这是首选选项。

Check here how you can get the execution plan of the query.在此处查看如何获取查询的执行计划。

------------------------------------------------------------------------------
| Id  | Operation             | Name | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |      | 10000 |  1044K|    25   (4)| 00:00:01 |
|*  1 |  HASH JOIN RIGHT OUTER|      | 10000 |  1044K|    25   (4)| 00:00:01 |
|*  2 |   TABLE ACCESS FULL   | B    |     2 |   110 |    16   (0)| 00:00:01 |
|   3 |   TABLE ACCESS FULL   | A    | 10000 |   507K|     8   (0)| 00:00:01 |
------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - access("A"."ID"="B"."FK_ID"(+))
   2 - filter("B"."COL3"(+) IS NULL AND "B"."COL2"(+) IS NULL AND 
              "B"."COL1"(+)=8)
          
          

A different situation will be if you limit the processed rows from the table A to a very small number, say using the same query with additional WHERE condition.如果您将表A中已处理的行限制为非常小的数量,例如使用带有附加WHERE条件的相同查询,则会出现不同的情况。

You will use a nested loop join and index access to get only the required rows.您将使用嵌套循环连接和索引访问来仅获取所需的行。

SELECT a.id, a.col1, a.col2, a.col3,
       b.col4
FROM a
LEFT OUTER JOIN b
             ON a.id  = b.fk_id AND
                b.col1 = 8 AND
                b.col2 IS NULL  AND
                b.col3 IS NULL 
where a.id = 8   --<<<< here you select only a few rows

Now you can profit from defining indices for现在您可以从为

  • access to table A with the WHERE predicate使用WHERE谓词访问表A
  • access to table B with the join columns使用join列访问表B

In our case it will be在我们的例子中,它将是

create index a_idx on a (id);
create index b_idx on b (fk_id,col1, col2, col3);

The execution plan that you should expect will be the nested loop outer join您应该期望的执行计划将是嵌套循环外连接

--------------------------------------------------------------------------------------
| Id  | Operation                    | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |       |     2 |   214 |     4   (0)| 00:00:01 |
|   1 |  NESTED LOOPS OUTER          |       |     2 |   214 |     4   (0)| 00:00:01 |
|   2 |   TABLE ACCESS BY INDEX ROWID| A     |     1 |    52 |     2   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN          | A_IDX |     1 |       |     1   (0)| 00:00:01 |
|   4 |   TABLE ACCESS BY INDEX ROWID| B     |     2 |   110 |     2   (0)| 00:00:01 |
|*  5 |    INDEX RANGE SCAN          | B_IDX |     1 |       |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   3 - access("A"."ID"=8)
   5 - access("B"."FK_ID"(+)=8 AND "B"."COL1"(+)=8 AND "B"."COL2"(+) IS NULL 
              AND "B"."COL3"(+) IS NULL)
       filter("B"."COL3"(+) IS NULL)   

                 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM