问题
I have a Oracle 12c query that will eventually be used in a BIRT report (in IBM's Maximo Asset Management platform).
The query/report will retrieve records as follows:
- Retrieve workorders based on the parameters that were selected by the user.
- All of the parameters are optional.
- For testing purposes, I'm using bind variables as parameters (in Toad for Oracle).
- It doesn't matter if the workorders are parents, children, or neither.
- Of the workorders that were retrieved, also select any children of those workorders.
- There are only two levels to the parent/child hierarchy: parents and children (no grandchildren, etc.)
The output looks like this:
The blue boxes show examples of parents with children.
The query:
--short form definitions:
--wo = workorder
--act = actual (actual cost, actual date, etc.)
--pmtr = parameters
with
wo_pmtr as ( --WOs filtered by parameters
select
wonum,
parent,
hierarchypath,
classstructureid,
division,
worktype,
status,
trunc(actstart) as actstart,
trunc(actfinish) as actfinish,
actlabcost,
actmatcost,
actservcost,
acttoolcost,
acttotalcost
from
workorder wo
where
--using bind variables as parameters in Toad
(:wonum is null or wonum = :wonum)
and (:division is null or division = :division)
and (:worktype is null or worktype = :worktype)
and (:status is null or status = :status)
and (:actstart is null or trunc(actstart) >= :actstart)
and (:actfinish is null or trunc(actfinish) <= :actfinish)
--retrieve workorders where the classification matches the parameter
--and retrieve any child classifications too
--the classification hierarchy is not to be confused with the workorder hierarchy
and (:classstructureid is null or (exists (select 1 from classancestor where ((ancestor = :classstructureid)) and (classstructureid=wo.classstructureid))))
)
select
wo_pmtr.wonum,
wo_pmtr.parent,
wo_pmtr.hierarchypath,
wo_pmtr.classstructureid,
wo_pmtr.division,
wo_pmtr.worktype,
wo_pmtr.status,
wo_pmtr.actstart,
wo_pmtr.actfinish,
wo_pmtr.actlabcost,
wo_pmtr.actmatcost,
wo_pmtr.actservcost,
wo_pmtr.acttoolcost,
wo_pmtr.acttotalcost,
coalesce(wo_pmtr.parent, wo_pmtr.wonum) parent_coalesced
from
wo_pmtr --WOs filtered by parameters
union --union will remove duplicates (unlike union all)
select --select children of the filtered WOs
wo.wonum,
wo.parent,
wo.hierarchypath,
wo.classstructureid,
wo.division,
wo.worktype,
wo.status,
trunc(wo.actstart) as actstart,
trunc(wo.actfinish) as actfinish,
wo.actlabcost,
wo.actmatcost,
wo.actservcost,
wo.acttoolcost,
wo.acttotalcost,
coalesce(wo.parent, wo.wonum) parent_coalesced
from
workorder wo --select from the base workorder table *without* filtering by the parameters
left join
wo_pmtr
on wo.parent = wo_pmtr.wonum
where
wo.parent is not null --where WO is a child
and wo_pmtr.wonum is not null --where WO is a child of the filtered WOs
--caution: some of those workorders might have already been selected via the parameters in the first query
--we need to eliminate duplicates if they exist (via the union)
order by
parent_coalesced,
hierarchypath
db<>fiddle here
Question:
The query makes several full table scans:
Is there a way to reduce the number of full table scans to improve performance?
回答1:
There are many indexes that you can use on the WORKORDER table. What stands out in your query is that you're not referring to the SITEID column which should almost always come with the WONUM as together they compose the "primary key", which in Oracle Maximo is a unique index.
You can confirm this by running this query:
select attributename from maxattribute where objectname='WORKORDER' AND PRIMARYKEYCOLSEQ IS NOT NULL;
Also, a good practice is to identify which indexes you will need to query the needed data. You can have a look at the table's indexes with your favorite SQL tool or from the Database Configuration Maximo application.
回答2:
full table scans are only required if no proper index is in place. So create such and you will see that the full table scans disappear
来源:https://stackoverflow.com/questions/64849333/select-workorders-via-parameters-and-their-children