我的目标是在student表上使用复合索引。学生表将内部连接到该xyz表上。我在student表上创建了索引,如下所示:
student
xyz
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'查询时那样使用索引,我只能看到主键作为索引。我是否在错误的表上创建了索引?出现的问题是我想使用复合键,但是,联接表不包含任何用于复合索引的列。
'EXPLAIN PLAN FOR'
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")
它按预期工作。Oracle完全按照您的要求做了。
您在上有一个复合索引phonenumber, email,而没有使用查询的 过滤谓词中 的任何列:
phonenumber, email
where months_between(SYSDATE, dateofbirth)/12 >= 18 and xyz.studentnumber is null;
所以没有理由甲骨文会做索引扫描 上phonenumber, email。您只需选择组合键的这些列,而不是对其进行过滤:
SELECT Phonenumber, email from student left join Xyz
*当您 *投影 这些列时,将使用 索引 ,而不仅是 SELECT 。该STUDENT表按预期进行,FULL TABLE SCAN因为它是普通选择,并且在索引列上不使用任何过滤器。如果要查看索引扫描的发生,请在过滤器下面添加:
STUDENT
FULL TABLE SCAN
AND phonenumber = <value> AND email = <value>