使用左连接时我可以有一个复合索引吗

Can i have a composite index on when using a left join

我的目的是在studenttable上使用复合索引。学生 table 将内联到 xyz table。我在学生 table 上创建了如下索引:

 CREATE INDEX email_phonenumber_student_idx
  ON student(phonenumber, email);

当我 运行 我的查询

SELECT Phonenumber, email from student 
left join enrolment on enrolment.studentnumber = student.studentnumber 
where months_between(SYSDATE, dateofbirth)/12 >= 18 and 
enrolment.studentnumber is null and 
student.phonenumber = '07123456788' and student.email = 'Chris@Lailasman.com’;

它按预期工作,但是当我 'EXPLAIN PLAN FOR' 查询时索引没有被使用,我只能看到主键作为索引。我是否在错误的 table 上创建了索引?出现的问题是我想使用复合键,但是,连接的 table 不包含任何用于复合索引使用的列。

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1388008413

---------------------------------------------------------------------------------------------
| Id  | Operation                    | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |              |     1 |    63 |     0   (0)| 00:00:01 |
|   1 |  NESTED LOOPS ANTI           |              |     1 |    63 |     0   (0)| 00:00:01 |
|*  2 |   TABLE ACCESS BY INDEX ROWID| STUDENT      |     1 |    50 |     0   (0)| 00:00:01 |
|*  3 |    INDEX UNIQUE SCAN         | SYS_C0022463 |     1 |       |     0   (0)| 00:00:01 |
|*  4 |   INDEX RANGE SCAN           | SYS_C0022468 |     1 |    13 |     0   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("STUDENT"."EMAIL"='Chris@Lailasman.com' AND
              MONTHS_BETWEEN(SYSDATE@!,INTERNAL_FUNCTION("STUDENT"."DATEOFBIRTH"))/12>=18)
   3 - access("STUDENT"."PHONENUMBER"='07123456788')
   4 - access("ENROLMENT"."STUDENTNUMBER"="STUDENT"."STUDENTNUMBER")

您的估计行数为“8”。索引对这种小表没有用。 Oracle 知道这一点,所以它只使用更简单的扫描技术。

使用索引会产生开销——例如,通常需要读取索引页和原始数据页。随着数据变大,它们很有用。

它按预期工作。 Oracle 完全按照您的要求去做。

CREATE INDEX email_phonenumber_student_idx
  ON student(phonenumber, email);

您在 phonenumber, email 上有一个复合索引,但您没有使用查询的 过滤谓词 中的任何列:

where months_between(SYSDATE, dateofbirth)/12 >= 18 
and  xyz.studentnumber is null;

所以 Oracle 没有理由在 phonenumber, email 上进行索引扫描。您只是 SELECT 组合键的那些列,而不是过滤它们:

SELECT Phonenumber, email 
from student left join Xyz

Index 将在您 PROJECT 那些列时使用,而不仅仅是 SELECT. STUDENT table 正如预期的那样用于 FULL TABLE SCAN 因为它是一个普通的 select 并且不在索引列上使用任何过滤器。如果您想查看索引扫描,请添加以下过滤器:

AND phonenumber = <value>
AND email = <value>