当使用左连接时,我可以使用复合索引吗?

问题描述 投票:0回答:1

我的目的是用一个综合指数对 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 = '[email protected]’;

它的工作原理是一样的,但索引没有被使用,因为当我 '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"='[email protected]' AND
              MONTHS_BETWEEN(SYSDATE@!,INTERNAL_FUNCTION("STUDENT"."DATEOFBIRTH"))/12>=18)
   3 - access("STUDENT"."PHONENUMBER"='07123456788')
   4 - access("ENROLMENT"."STUDENTNUMBER"="STUDENT"."STUDENTNUMBER")
sql database oracle syntax sqlplus
1个回答
1
投票

它和预期的一样工作。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;

所以甲骨文公司没有理由对你的查询进行索引扫描 关于 phonenumber, email. 你只是简单地选择那些复合键的列,而不是过滤它们。

SELECT Phonenumber, email 
from student left join Xyz

索引 将在您 项目 这些列,不仅仅是 选择. 该 STUDENT 桌子 FULL TABLE SCAN 因为它是一个普通的选择,并且没有在索引列上使用任何过滤器。如果你想看到索引扫描的发生,那么添加下面的过滤器。

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

1
投票

你的估计行数是 "8"。 索引对于这样的小表是没有用的。 Oracle知道这一点,所以它只是使用更简单的扫描技术。

使用索引是有开销的--比如,往往索引和原始数据页都需要被读取。 当数据变大时,索引就有用了。

© www.soinside.com 2019 - 2024. All rights reserved.