关于sql优化——索引的使用
有一个视图如下:
Select a.WKI_ID AS wf_workitem_id,
a.WKI_Name AS wf_workitem_name, j.user_name as wf_from_user_name,
a.WKI_CreateTime AS wf_create_date,a.wki_checkintime as wf_checkin_date, a.WKI_Desc AS wf_workitem_url,
a.wki_state,a.wki_user,a.wki_checkouttime,
c.PRI_ID AS wf_process_instance_id,
d.wka_applyman,
g.BUSINESS_ID AS wf_business_id,
g.PROJECT_ID AS wf_project_id,
h.PRJ_TITLE AS wf_project_title,
h.PRJ_BUSS_TYPE AS wf_business_type,
h.PRJ_BUSS_NAME AS wf_business_name, k.TIME_LIMIT AS wf_workitem_timelimit,
k.TIME_USED AS wf_workitem_timeused, k.TIME_LEFT AS wf_workitem_timeleft,
e.atd_id,e.atd_tamid
l.act_max_timeout
,decode((select count(*) from wf_workitem_urge m where m.wki_id=a.wki_id),0,'no') as ifHaveUrge
FROM WorkItem a
INNER JOIN ActiInstance b ON a.WKI_AtiID = b.ATI_ID
INNER JOIN ProcInstance c ON b.ATI_PriID = c.PRI_ID
INNER JOIN WF_PROCESS_BUSINESS_REL g ON c.PRI_ID = g.PRO_INST_ID
INNER JOIN WF_PUBLIC_PROJECT_INFO h ON g.PROJECT_ID = h.PROJECT_ID
INNER JOIN ProcDefinition f ON f.PRD_ID = c.PRI_PrdID
LEFT OUTER JOIN WorkitemApply d ON a.WKI_ID = d.WKA_WkiID
INNER JOIN ActiDefinition e ON b.ATI_AtdID = e.ATD_ID
LEFT OUTER JOIN WF_WORKITEM_REL i ON a.WKI_ID = i.TO_ITEM_ID
LEFT OUTER JOIN WF_USER j ON j.USER_ID = i.FROM_USER_ID
INNER JOIN WF_WORKITEM_PROCESS_TIME k ON a.WKI_ID = k.WORKITEM_ID
LEFT JOIN wf_actinstance_ext l On b.ATI_ID = l.act_instance_id
INNER JOIN workitemreledata m on a.wki_id = m.WKR_WKIID
where m.WKR_VARIABLENAME='isNeedSignIn' and m.WKR_NUMBVALUE!=1
其中,oracle执行计划如下:
SELECT STATEMENT, GOAL = CHOOSE Cost=206 Cardinality=302 Bytes=208078
HASH JOIN Cost=206 Cardinality=302 Bytes=208078
NESTED LOOPS Cost=187 Cardinality=302 Bytes=200226
NESTED LOOPS Cost=144 Cardinality=43 Bytes=21672
HASH JOIN Cost=144 Cardinality=43 Bytes=21113
HASH JOIN Cost=141 Cardinality=43 Bytes=19049
HASH JOIN OUTER Cost=133 Cardinality=43 Bytes=17931
NESTED LOOPS Cost=130 Cardinality=43 Bytes=16985
NESTED LOOPS OUTER Cost=102 Cardinality=28 Bytes=9968
HASH JOIN OUTER Cost=82 Cardinality=20 Bytes=6540
HASH JOIN Cost=77 Cardinality=20 Bytes=6140
HASH JOIN OUTER Cost=73 Cardinality=20 Bytes=5100
NESTED LOOPS Cost=69 Cardinality=20 Bytes=4500
TABLE ACCESS FULL Object owner=YZH Object name=WORKITEMRELEDATA Cost=49 Cardinality=20 Bytes=1060
TABLE ACCESS BY INDEX ROWID Object owner=YZH Object name=WORKITEM Cost=1 Cardinality=1 Bytes=172
INDEX UNIQUE SCAN Object owner=YZH Object name=PK_WORKITEM Cardinality=1
TABLE ACCESS FULL Object owner=YZH Object name=WORKITEMAPPLY Cost=3 Cardinality=1062 Bytes=31860
TABLE ACCESS FULL Object owner=YZH Object name=WF_WORKITEM_PROCESS_TIME Cost=3 Cardinality=1062 Bytes=55224
INDEX FAST FULL SCAN Object owner=YZH Object name=PK_WORKITEM_REL Cost=4 Cardinality=1634 Bytes=32680
TABLE ACCESS BY INDEX ROWID Object owner=YZH Object name=WF_USER Cost=1 Cardinality=1 Bytes=29
INDEX UNIQUE SCAN Object owner=YZH Object name=PK_WF_USER Cardinality=1
TABLE ACCESS BY INDEX ROWID Object owner=YZH Object name=ACTIINSTANCE Cost=1 Cardinality=2 Bytes=78
INDEX UNIQUE SCAN Object owner=YZH Object name=PK_ACTIINSTANCE Cardinality=1
TABLE ACCESS FULL Object owner=YZH Object name=WF_ACTINSTANCE_EXT Cost=2 Cardinality=409 Bytes=8998
TABLE ACCESS FULL Object owner=YZH Object name=PROCINSTANCE Cost=7 Cardinality=4738 Bytes=123188
TABLE ACCESS FULL Object owner=YZH Object name=WF_PROCESS_BUSINESS_REL Cost=2 Cardinality=409 Bytes=19632
INDEX UNIQUE SCAN Object owner=YZH Object name=PK_PROCDEFINITION Cardinality=1 Bytes=13
TABLE ACCESS BY INDEX ROWID Object owner=YZH Object name=WF_PUBLIC_PROJECT_INFO Cost=1 Cardinality=7 Bytes=1113
INDEX UNIQUE SCAN Object owner=YZH Object name=PK_WF_PUBLIC_PROJECT_INFO Cardinality=1
TABLE ACCESS FULL Object owner=YZH Object name=ACTIDEFINITION Cost=12 Cardinality=8414 Bytes=218764
现在问题是,我的c.PRI_ID 和 g.PRO_INST_ID都是主键,为什么PROCINSTANCE表会造成全表查询?还有我的e.atd_id也是主键,为什么ACTIDEFINITION表也会造成全表查询?我把e.atd_tamid这个字段去掉就不会使用全表查询而使用索引了。