使用左连接时我可以有一个复合索引吗
Can i have a composite index on when using a left join
我的目的是在student
table上使用复合索引。学生 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>
我的目的是在student
table上使用复合索引。学生 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>