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

对着背影说爱祢 提交于 2020-05-24 05:06:29

问题


My aim is to use a composite index on the student table. The Student table will be inner joined onto the xyz table. I created my index on the student table as follows:

 CREATE INDEX email_phonenumber_student_idx
  ON student(phonenumber, email);

When I run my query

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’;

It works as intended, but the index is not being used as when I 'EXPLAIN PLAN FOR' the query, I can only see the primary key as the index. Have I created the index on the wrong table? The issue arises is that I wanted to make use of a composite key, however, the joined table does not contain any columns for composite index use.

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")

回答1:


Your estimated rows are "8". Indexes are not useful for such small tables. Oracle knows that so it just uses simpler scanning techniques.

There is an overhead to using indexes -- for instance, often both the index and the original data pages need to be read. They are useful as the data becomes larger.




回答2:


It works as expected. Oracle did exactly what you asked it to do.

CREATE INDEX email_phonenumber_student_idx
  ON student(phonenumber, email);

You have a composite index on phonenumber, email, while you do not use any of the columns in the filter predicate of your query:

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

So there is no reason why Oracle would do an index scan on phonenumber, email. You are simply SELECTing those columns of composite key, not filtering them:

SELECT Phonenumber, email 
from student left join Xyz

Index will be used when you PROJECT those columns, not just SELECT. The STUDENT table as expected goes for a FULL TABLE SCAN as it is a plain select and doesn't use any filter on the indexed columns. If you want to see an index scan happening, then add below filter:

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


来源:https://stackoverflow.com/questions/61850728/can-i-have-a-composite-index-on-when-using-a-left-join

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!